linux shell 批量修改文件后缀名

rename 's/\.csv/\.txt/' *

linux shell 批量转换文件名大小写

rename 'y/A-Z/a-z/' *

(反着写就是小写变大写)

linux shell 删除所有文件的后缀名

rename 's/.csv//' *

或者

rename 's/\.bak$//' *.bak

linux shell 给所有文件添加后缀名

rename 's/$/\.txt/'  *

linux shell 在所有文件名前添加某个字符串

rename 's/^/const/' *

hexdump 十六进制输出数据

echo -ne "const.net.cn" |hexdump -C

00000000 63 6f 6e 73 74 2e 6e 65 74 2e 63 6e |const.net.cn|
0000000c

echo -ne "const.net.cn" |hexdump -e '16/1 "%02X " "\n"'

63 6F 6E 73 74 2E 6E 65 74 2E 63 6E

linux shell 执行字符串命令

cmd="echo hello word"
$cmd

或者

eval $cmd

linux shell date string

Date FormatOption MeaningExample Output
date +%clocale’s date timeSat May 9 11:49:47 2020
date +%xlocale’s date05/09/20
date +%Xlocale’s time11:49:47
date +%Alocale’s full weekday nameSaturday
date +%Blocale’s full month nameMay
date +%m-%d-%YMM-DD-YYYY date format05-09-2020
date +%DMM/DD/YY date format05/09/20
date +%FYYYY-MM-DD date format2020-05-09
date +%THH:MM:SS time format11:44:15
date +%uDay of Week6
date +%UWeek of Year with Sunday as first day of week18
date +%VISO Week of Year with Monday as first day of week19
date +%jDay of Year130
date +%ZTimezonePDT
date +%mMonth of year (MM)05
date +%dDay of Month (DD)09
date +%YYear (YY)2020
date +%HHour (HH)11
date +%HHour (HH) in 24-hour clock format11
date +%IHour in 12-hour clock format11
date +%plocale’s equivalent of AM or PMAM
date +%Psame as %p but in lower caseam
date '+%F %T'

2021-12-30 16:26:50

linux 编码转换显示hexstring

echo -n d6d0b9fa |xxd -r -p |iconv -f gb2312 -t utf8

中国

echo -n 中国 |iconv -f utf8 -t gb2312 |xxd -p

d6d0b9fa

echo -n 中国 |xxd -p

e4b8ade59bbd

echo -n e4b8ade59bbd |xxd -r -p

中国

使用ss 查看网络监听连接

ss -nlput
ss -h

-h, --help this message
-V, --version output version information
-n, --numeric don't resolve service names
-r, --resolve resolve host names
-a, --all display all sockets
-l, --listening display listening sockets
-o, --options show timer information
-e, --extended show detailed socket information
-m, --memory show socket memory usage
-p, --processes show process using socket
-i, --info show internal TCP information
--tipcinfo show internal tipc socket information
-s, --summary show socket usage summary
--tos show tos and priority information
-b, --bpf show bpf filter socket information
-E, --events continually display sockets as they are destroyed
-Z, --context display process SELinux security contexts
-z, --contexts display process and socket SELinux security contexts
-N, --net switch to the specified network namespace name

-4, --ipv4 display only IP version 4 sockets
-6, --ipv6 display only IP version 6 sockets
-0, --packet display PACKET sockets
-t, --tcp display only TCP sockets
-S, --sctp display only SCTP sockets
-u, --udp display only UDP sockets
-d, --dccp display only DCCP sockets
-w, --raw display only RAW sockets
-x, --unix display only Unix domain sockets
--tipc display only TIPC sockets
--vsock display only vsock sockets
-f, --family=FAMILY display sockets of type FAMILY
FAMILY := {inet|inet6|link|unix|netlink|vsock|tipc|xdp|help}

-K, --kill forcibly close sockets, display what was closed
-H, --no-header Suppress header line
-O, --oneline socket's data printed on a single line

显示所有IP地址

ip -4 a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.10.8/24 brd 192.168.10.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 192.168.1.64/24 brd 192.168.1.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 192.168.3.64/24 brd 192.168.3.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 192.169.5.64/24 brd 192.169.5.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 192.168.6.64/24 brd 192.168.6.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 192.168.2.64/24 brd 192.168.2.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever

linux shell directory md5sum
使用md5sum 校验整个目录
生成md5sum.txt

find . -type f |xargs md5sum > /path/to/file/md5sum.txt
md5sum -c /path/to/file/md5sum.txt

listing md5sum for all files
Therefore you should be able to run this command to get the result you want:

find -type f -exec md5sum "{}" +

If you really want to use pipe, then you need to tell find to delimit the responses with a null and xargs to expect null delimited arguments like this:

find -type f -print0 |xargs -0 md5sum

linux shell 写一条日志记录到syslog
Log a message to your client, eg:

logger -t hello-world -s 'Hello World - 1'

获取网卡mac地址,并设置为hostname

hostname `cat /sys/class/net/eth0/address |sed 's/://g'`

iptables 自动保存

sudo apt-get install iptables-persistent

sm2算法的公钥是64字节,私钥是32字节,公钥其实是由坐标点(x,y)组合构成,即每个点都是32字节的大数构成的。但是大多数情况下在使用的时候都是对公钥进行压缩使用,以节省空间。但是根据点压缩方式,我们在使用的时候看到的压缩公钥有两种,一种是02,一种是03。还有04的标识未压缩。
02/03表示一种压缩方式,所以在解压缩的时候根据压缩标志对Y坐标进行不同的反转操作。如何解压缩呢,前面讲到SM2算法采用的曲线公式,因此当知道坐标X就可以根据该公式算出Y坐标,进而得到完整的公钥。

sm2 压缩与还原
简单来说,就是判断最低位是奇数还是偶数,偶数为0(compressed_y_0),奇数为1(compressed_y_1).

ECC/SM2 公钥(点)压缩方法,64字节公钥压缩成33字节公钥。

void compress(const uint8_t *public_key, uint8_t *compressed)
{
    int i;
    for (i = 0; i < 32; ++i)
    {
        compressed[i+1] = public_key[i];
    }
    compressed[0] = 2 + (public_key[32 * 2 - 1] & 0x01);
}

树莓派介绍
树莓派(英语:Raspberry Pi)英国树莓派基金会开发的微型单板计算机,目的是以低价硬件及自由软件促进学校的基本计算机科学教育。

树莓派系列计算机每一代均使用博通(Broadcom)出产的ARM架构处理器,如今生产的机型(树莓派4B)内存在2GB和8GB之间,主要TF卡作为系统存储媒体(初代使用SD卡),配备USB接口和HDMI的视频输出(支持声音输出),内置Ethernet/WLAN/Bluetooth网络链接的方式(依据型号决定),并且可使用多种操作系统。产品线型号分为A型、B型、Zero型和ComputeModule计算卡。

Raspberry Pi OS是官方推出的操作系统,适用于所有型号的树莓派。

树莓派shadowsocks解决method aes-256-gcm not supported方法
sudo apt install python3 && sudo apt install python3-pip
sudo pip install https://github.com/shadowsocks/shadowsocks/archive/master.zip -U
sudo apt-get install -y libsodium*

树莓派 ss shadowsocks-for-raspberry
sudo vim /etc/shadowsocks/config.json 编辑服务器的信息
使用sudo sslocal -c /etc/shadowsocks/config.json -d -start 就可以运行ss了
设置开机自动启动,新建一个sh脚本,输入下列代码,加入执行权限,sudo chmod 755 shadowsocks.sh, 然后编辑开机启动脚本sudo vim /etc/rc.local,在exit 0 之前加入/home/pi/Documents/shadowsocks.sh

sudo sslocal -c /etc/shadowsocks/config.json -d start

OK,shadowsocks就安装好了,但是socks5不支持http和https的协议,所以还需要安装代理

树莓派 安装privoxy
安装privoxy, sudo apt-get install privoxy
配置privoxy,sudo vim /etc/privoxy/config,找到并修改为以下代码

listen-address  127.0.0.1:8118
forward-socks5   /               127.0.0.1:1080 .
# 访问局域网不走ss
forward         192.168.*.*/     .
forward            10.*.*.*/     .
forward           127.*.*.*/     .

启动privoxy,systemctl start privoxy
现在进行测试,curl google.com --proxy 127.0.0.1:8118,如果有结果那么配置成功了,现在可以通过privoxy代理任意程序了
树莓派 you-get

sudo pip3 install you-get
you-get -V

you-get: version 0.4.1555, a tiny downloader that scrapes the web.

安装apache2

sudo apt install apache2 -y

安装php

sudo apt install php -y

restart Apache2:

sudo service apache2 restart

Install MySQL (MariaDB Server) on Raspberry Pi
MySQL (often pronounced My S–Q–L) is a popular open source relational database.
Install the MySQL Server (MariaDB Server) and PHP-MySQL packages by entering the following command:

sudo apt install mariadb-server php-mysql -y
sudo service apache2 restart
sudo mysql_secure_installation

To install phpMyAdmin on a Raspberry Pi, type the following command into the terminal:

sudo apt install phpmyadmin -y

Enable the PHP MySQLi extension and restart Apache2 for changes to take effect:

sudo phpenmod mysqli
sudo service apache2 restart

如果/var/www/html/目录下面没有phpmyadmin文件夹,执行下面命令

sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin

访问localhost/phpmyadmin,如果出现HY000/1698错误:
mysqli_real_connect(): (HY000/1698): Access denied for user 'root'@'localhost'
解决办法:
sudo mysql -uroot -p

输入密码成功登录后,建立一个新的用户,并给予最大的权限:

CREATE USER '新用户'@'%' IDENTIFIED BY '新用户的密码';
GRANT ALL PRIVILEGES ON . TO '新用户'@'%' WITH GRANT OPTION;

好了,用你的新用户名和密码去登录phpmyadmin吧。

建议步骤:

sudo chown -R pi:www-data /var/www/html/
sudo chmod -R 770 /var/www/html/

linux nobody socket bind

sudo setcap CAP_NET_BIND_SERVICE=+eip /path/to/binary

raspberrypi 关闭wifi
运行以下命令来确保rfkill的安装。

sudo apt install rfkill

禁用Raspberry Pi上的Wi-Fi接口

sudo rfkill block wifi

禁用你的蓝牙连接。

sudo rfkill block bluetooth

想恢复连接的功能,你可以运行以下命令。

sudo rfkill unblock wifi

raspberrypi 供电不足 异常

当+5V电源输入电压不足时,显示屏的右上角会显示一个黄色的小闪电符号作为报警。 +5V电源输入电压不足会引起很多问题,比如运行不稳定,数据丢失,甚至会导致SD卡永久损坏。 使用一个优质的、足功率、足电压的电源适配器是必须的。但即使我们使用官方电源适配器,偶尔也会因为micro USB口长期反复插拔后,导致接触不良而引起接触电阻过高,使得树莓派+5V输入电压不足。 于是我们需要有能够实时监测树莓派电压不足(Under-voltage)的方法,以便能够在所开发的应用中及时报警,或者采取相应行动。

原理
Raspberry Pi OS 中的命令 vcgencmd get_throttled 会得到一个十六进制数,这个数字反映了和当前系统频率、输入电压等相关的状态信息

$ vcgencmd get_throttled

throttled=0x50005

这个数字转换为二进制后,其中的8位,代表了8个标志的状态,我们重点看其中的两位:

这个数字的第 0 位为 1 的话,表明当前发生了输入电压不足的情况;
这个数字的第 16 位为 1 的话,表明启动之后曾经发生过输入电压不足的情况;
那我们只要实时检测这两个标志位,就可以监测到树莓派输入电压不足的情况。

#Flag Bits
UNDERVOLTED         = '0'
CAPPED              = '1'
THROTTLED           = '2'
SOFT_TEMPLIMIT      = '3'
HAS_UNDERVOLTED     = '16'
HAS_CAPPED          = '17'
HAS_THROTTLED       = '18'
HAS_SOFT_TEMPLIMIT  = '19'

UNDERVOLTED 说明输入电压过低了
THROTTLED 表明系统工作频率被强制降低了
HAS_UNDERVOLTED 说明曾经检测到电压过低的情况,
HAS_THROTTLED 说明曾经被降频

raspberrypi 降低功率
禁用 HDMI 输出
估计省电:约 30mA。

在无头配置中使用 Raspberry Pi 时,根据定义,您也不需要连接显示器。如果是这种情况,您也可以禁用 HDMI 输出。

要禁用 Raspberry Pi 上的 HDMI 输出,请执行以下命令:

sudo /opt/vc/bin/tvservice -o

然后,要在再次需要时重新启用 HDMI 输出,请使用以下命令:

sudo /opt/vc/bin/tvservice -p

与禁用 USB 控制器一样,重新启动后启用 HDMI 输出。

openssl read rsa private key from string

string key = "-----BEGIN RSA PRIVATE KEY-----\n"
"MIIBOgIBAAJBALFKg42Tog/eoSxoyIPkOBDq5adIK8WNYtOO1IV5nYFZ/O8W6bsT\n"
"7+MjFy376TIQAavv6bdoBAmbzyN1BAQAbzECAwEAAQJAPz9p9xP3+NlffkxTXFoK\n"
"dl6WVzs0AmISI48M2iEsw3wS6auo09AUKg70mP0ueU/GlKsVY78CFzSfSLJUtGdY\n"
"AQIhANmovwa/oL5/HwS/IHRNk1r2ZvUnfPTc90zCW9EqZxFhAiEA0IViaiYkqcSw\n"
"IC+uTn+B87OLvGHLX4UKk1CRoMwQn9ECIEJPdJMbwl8G325UxBBqqd/mfYtmkl0P\n"
"DJBoDgz1PB1BAiEAtLdE6bYRBEkAU4S/TizXlTvAGQ2wUiJdXfrvmyoAJmECIBkM\n"
"IODUSpheA8692yYgQ6t/m8EEIVd2I7K8ebZXr2sc\n"
"-----END RSA PRIVATE KEY-----\n";
BIO* bo = BIO_new(BIO_s_mem());
BIO_write(bo, key.c_str(), key.length());
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bo, nullptr, 0, 0 );
RSA* rsa = EVP_PKEY_get1_RSA( pkey );

openssl 默认生成的rsa密码是pkcs1格式的,java的默认格式是pkcs8的。openssl本身对于pkcs8与pkcs1都是支持的。

string key = "-----BEGIN PRIVATE KEY-----\n"
"MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAsUqDjZOiD96hLGjI\n"
"g+Q4EOrlp0grxY1i047UhXmdgVn87xbpuxPv4yMXLfvpMhABq+/pt2gECZvPI3UE\n"
"BABvMQIDAQABAkA/P2n3E/f42V9+TFNcWgp2XpZXOzQCYhIjjwzaISzDfBLpq6jT\n"
"0BQqDvSY/S55T8aUqxVjvwIXNJ9IslS0Z1gBAiEA2ai/Br+gvn8fBL8gdE2TWvZm\n"
"9Sd89Nz3TMJb0SpnEWECIQDQhWJqJiSpxLAgL65Of4Hzs4u8YctfhQqTUJGgzBCf\n"
"0QIgQk90kxvCXwbfblTEEGqp3+Z9i2aSXQ8MkGgODPU8HUECIQC0t0TpthEESQBT\n"
"hL9OLNeVO8AZDbBSIl1d+u+bKgAmYQIgGQwg4NRKmF4Dzr3bJiBDq3+bwQQhV3Yj\n"
"srx5tlevaxw=\n"
"-----END PRIVATE KEY-----\n";    
BIO* bo = BIO_new(BIO_s_mem());
BIO_write(bo, key.c_str(), key.length());
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bo, nullptr, 0, 0 );
RSA* rsa = EVP_PKEY_get1_RSA( pkey );

openssl 生成rsa 私钥

openssl genrsa -out rsa_private.pem 512

Generating RSA private key, 512 bit long modulus (2 primes)
...........+++++++++++++++++++++++++++
..............+++++++++++++++++++++++++++
e is 65537 (0x010001)

cat rsa_private.pem 

-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBALFKg42Tog/eoSxoyIPkOBDq5adIK8WNYtOO1IV5nYFZ/O8W6bsT
7+MjFy376TIQAavv6bdoBAmbzyN1BAQAbzECAwEAAQJAPz9p9xP3+NlffkxTXFoK
dl6WVzs0AmISI48M2iEsw3wS6auo09AUKg70mP0ueU/GlKsVY78CFzSfSLJUtGdY
AQIhANmovwa/oL5/HwS/IHRNk1r2ZvUnfPTc90zCW9EqZxFhAiEA0IViaiYkqcSw
IC+uTn+B87OLvGHLX4UKk1CRoMwQn9ECIEJPdJMbwl8G325UxBBqqd/mfYtmkl0P
DJBoDgz1PB1BAiEAtLdE6bYRBEkAU4S/TizXlTvAGQ2wUiJdXfrvmyoAJmECIBkM
IODUSpheA8692yYgQ6t/m8EEIVd2I7K8ebZXr2sc
-----END RSA PRIVATE KEY-----

openssl pkcs1转pkcs8

openssl pkcs8 -topk8 -inform pem -in rsa_private.pem -outform pem -nocrypt -out rsa_private_pkcs8.pem

cat rsa_private_pkcs8.pem 

-----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAsUqDjZOiD96hLGjI
g+Q4EOrlp0grxY1i047UhXmdgVn87xbpuxPv4yMXLfvpMhABq+/pt2gECZvPI3UE
BABvMQIDAQABAkA/P2n3E/f42V9+TFNcWgp2XpZXOzQCYhIjjwzaISzDfBLpq6jT
0BQqDvSY/S55T8aUqxVjvwIXNJ9IslS0Z1gBAiEA2ai/Br+gvn8fBL8gdE2TWvZm
9Sd89Nz3TMJb0SpnEWECIQDQhWJqJiSpxLAgL65Of4Hzs4u8YctfhQqTUJGgzBCf
0QIgQk90kxvCXwbfblTEEGqp3+Z9i2aSXQ8MkGgODPU8HUECIQC0t0TpthEESQBT
hL9OLNeVO8AZDbBSIl1d+u+bKgAmYQIgGQwg4NRKmF4Dzr3bJiBDq3+bwQQhV3Yj
srx5tlevaxw=
-----END PRIVATE KEY-----

openssl 从rsa私钥中提取公钥

openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem

writing RSA key

cat rsa_public.pem 

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALFKg42Tog/eoSxoyIPkOBDq5adIK8WN
YtOO1IV5nYFZ/O8W6bsT7+MjFy376TIQAavv6bdoBAmbzyN1BAQAbzECAwEAAQ==
-----END PUBLIC KEY-----

openssl rsa -in rsa_private_pkcs8.pem -pubout -out rsa_public_pkcs8.pem

writing RSA key

cat rsa_public_pkcs8.pem 

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALFKg42Tog/eoSxoyIPkOBDq5adIK8WN
YtOO1IV5nYFZ/O8W6bsT7+MjFy376TIQAavv6bdoBAmbzyN1BAQAbzECAwEAAQ==
-----END PUBLIC KEY-----

openssl rsa 私钥内容构成
私钥(rsa_private.pem)包括:modulus(n), public exponent(e), private exponent(d), prime 1(p), prime 2(q), exponent 1(exp1), exponent 2(exp2) and coefficient(coeff)。公钥(rsa_public.pem)包括:modulus(n) and public exponent(e)。其中n、e、d会被直接用于加密、解密,其它几个用来校验。

openssl read rsa private key from pem file

RSA* getRSA(string pemfile, bool bprikey)
{
    FILE *fp = fopen(pemfile.c_str(), "rb");
    if(!fp)
    {
        return nullptr;
    }

    RSA* rsa = nullptr;
    if(bprikey)
    {
        rsa = PEM_read_RSAPrivateKey(fp, nullptr, nullptr, nullptr);
    }
    else
    {
        rsa = PEM_read_RSA_PUBKEY(fp, nullptr, nullptr, nullptr);
    }
    fclose(fp);
    
    return rsa;
}

openssl PEM与DER文件格式说明
PEM格式就是在DER格式基础上进行BASE64编码,然后添加一些头尾信息或标签组成的,用于说明当前的文件格式,是一种约定俗称,如头信息为” -----BEGIN RSA PRIVATE KEY-----”,尾信息为” -----END RSA PRIVATE KEY-----”,中间的数据部分即是对DER进行base64编码后的结果。
示例:

echo -n 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALFKg42Tog/eoSxoyIPkOBDq5adIK8WNYtOO1IV5nYFZ/O8W6bsT7+MjFy376TIQAavv6bdoBAmbzyN1BAQAbzECAwEAAQ==' |base64 --decode |hexdump -e '16/1 "%02X " "\n"'

30 5C 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05
00 03 4B 00 30 48 02 41 00 B1 4A 83 8D 93 A2 0F
DE A1 2C 68 C8 83 E4 38 10 EA E5 A7 48 2B C5 8D
62 D3 8E D4 85 79 9D 81 59 FC EF 16 E9 BB 13 EF
E3 23 17 2D FB E9 32 10 01 AB EF E9 B7 68 04 09
9B CF 23 75 04 04 00 6F 31 02 03 01 00 01

echo -n 'MIIBOgIBAAJBALFKg42Tog/eoSxoyIPkOBDq5adIK8WNYtOO1IV5nYFZ/O8W6bsT7+MjFy376TIQAavv6bdoBAmbzyN1BAQAbzECAwEAAQJAPz9p9xP3+NlffkxTXFoKdl6WVzs0AmISI48M2iEsw3wS6auo09AUKg70mP0ueU/GlKsVY78CFzSfSLJUtGdYAQIhANmovwa/oL5/HwS/IHRNk1r2ZvUnfPTc90zCW9EqZxFhAiEA0IViaiYkqcSwIC+uTn+B87OLvGHLX4UKk1CRoMwQn9ECIEJPdJMbwl8G325UxBBqqd/mfYtmkl0PDJBoDgz1PB1BAiEAtLdE6bYRBEkAU4S/TizXlTvAGQ2wUiJdXfrvmyoAJmECIBkMIODUSpheA8692yYgQ6t/m8EEIVd2I7K8ebZXr2sc' |base64 --decode |hexdump -e '16/1 "%02X " "\n"'

30 82 01 3A 02 01 00 02 41 00 B1 4A 83 8D 93 A2
0F DE A1 2C 68 C8 83 E4 38 10 EA E5 A7 48 2B C5
8D 62 D3 8E D4 85 79 9D 81 59 FC EF 16 E9 BB 13
EF E3 23 17 2D FB E9 32 10 01 AB EF E9 B7 68 04
09 9B CF 23 75 04 04 00 6F 31 02 03 01 00 01 02
40 3F 3F 69 F7 13 F7 F8 D9 5F 7E 4C 53 5C 5A 0A
76 5E 96 57 3B 34 02 62 12 23 8F 0C DA 21 2C C3
7C 12 E9 AB A8 D3 D0 14 2A 0E F4 98 FD 2E 79 4F
C6 94 AB 15 63 BF 02 17 34 9F 48 B2 54 B4 67 58
01 02 21 00 D9 A8 BF 06 BF A0 BE 7F 1F 04 BF 20
74 4D 93 5A F6 66 F5 27 7C F4 DC F7 4C C2 5B D1
2A 67 11 61 02 21 00 D0 85 62 6A 26 24 A9 C4 B0
20 2F AE 4E 7F 81 F3 B3 8B BC 61 CB 5F 85 0A 93
50 91 A0 CC 10 9F D1 02 20 42 4F 74 93 1B C2 5F
06 DF 6E 54 C4 10 6A A9 DF E6 7D 8B 66 92 5D 0F
0C 90 68 0E 0C F5 3C 1D 41 02 21 00 B4 B7 44 E9
B6 11 04 49 00 53 84 BF 4E 2C D7 95 3B C0 19 0D
B0 52 22 5D 5D FA EF 9B 2A 00 26 61 02 20 19 0C
20 E0 D4 4A 98 5E 03 CE BD DB 26 20 43 AB 7F 9B
C1 04 21 57 76 23 B2 BC 79 B6 57 AF 6B 1C
此处解码后数据,与下面pem转der的内容一致。
openssl pem 转 der

openssl rsa -in rsa_private.pem -outform der -out rsa_private.der

writing RSA key

hexdump -e '16/1 "%02X " "\n"' rsa_private.der 

30 82 01 3A 02 01 00 02 41 00 B1 4A 83 8D 93 A2
0F DE A1 2C 68 C8 83 E4 38 10 EA E5 A7 48 2B C5
8D 62 D3 8E D4 85 79 9D 81 59 FC EF 16 E9 BB 13
EF E3 23 17 2D FB E9 32 10 01 AB EF E9 B7 68 04
09 9B CF 23 75 04 04 00 6F 31 02 03 01 00 01 02
40 3F 3F 69 F7 13 F7 F8 D9 5F 7E 4C 53 5C 5A 0A
76 5E 96 57 3B 34 02 62 12 23 8F 0C DA 21 2C C3
7C 12 E9 AB A8 D3 D0 14 2A 0E F4 98 FD 2E 79 4F
C6 94 AB 15 63 BF 02 17 34 9F 48 B2 54 B4 67 58
01 02 21 00 D9 A8 BF 06 BF A0 BE 7F 1F 04 BF 20
74 4D 93 5A F6 66 F5 27 7C F4 DC F7 4C C2 5B D1
2A 67 11 61 02 21 00 D0 85 62 6A 26 24 A9 C4 B0
20 2F AE 4E 7F 81 F3 B3 8B BC 61 CB 5F 85 0A 93
50 91 A0 CC 10 9F D1 02 20 42 4F 74 93 1B C2 5F
06 DF 6E 54 C4 10 6A A9 DF E6 7D 8B 66 92 5D 0F
0C 90 68 0E 0C F5 3C 1D 41 02 21 00 B4 B7 44 E9
B6 11 04 49 00 53 84 BF 4E 2C D7 95 3B C0 19 0D
B0 52 22 5D 5D FA EF 9B 2A 00 26 61 02 20 19 0C
20 E0 D4 4A 98 5E 03 CE BD DB 26 20 43 AB 7F 9B
C1 04 21 57 76 23 B2 BC 79 B6 57 AF 6B 1C

openssl asn1parse 使用

openssl asn1parse -i -in rsa_private.pem 

0:d=0 hl=4 l= 314 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=2 l= 65 prim: INTEGER :B14A838D93A20FDEA12C68C883E43810EAE5A7482BC58D62D38ED485799D8159FCEF16E9BB13EFE323172DFBE9321001ABEFE9B76804099BCF23750404006F31
74:d=1 hl=2 l= 3 prim: INTEGER :010001
79:d=1 hl=2 l= 64 prim: INTEGER :3F3F69F713F7F8D95F7E4C535C5A0A765E96573B34026212238F0CDA212CC37C12E9ABA8D3D0142A0EF498FD2E794FC694AB1563BF0217349F48B254B4675801
145:d=1 hl=2 l= 33 prim: INTEGER :D9A8BF06BFA0BE7F1F04BF20744D935AF666F5277CF4DCF74CC25BD12A671161
180:d=1 hl=2 l= 33 prim: INTEGER :D085626A2624A9C4B0202FAE4E7F81F3B38BBC61CB5F850A935091A0CC109FD1
215:d=1 hl=2 l= 32 prim: INTEGER :424F74931BC25F06DF6E54C4106AA9DFE67D8B66925D0F0C90680E0CF53C1D41
249:d=1 hl=2 l= 33 prim: INTEGER :B4B744E9B6110449005384BF4E2CD7953BC0190DB052225D5DFAEF9B2A002661
284:d=1 hl=2 l= 32 prim: INTEGER :190C20E0D44A985E03CEBDDB262043AB7F9BC10421577623B2BC79B657AF6B1C

openssl asn1parse -i -in rsa_public.pem

0:d=0 hl=2 l= 92 cons: SEQUENCE
2:d=1 hl=2 l= 13 cons: SEQUENCE
4:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
15:d=2 hl=2 l= 0 prim: NULL
17:d=1 hl=2 l= 75 prim: BIT STRING

在解析rsa_public.pem文件时没有显示出数据,其中BIT STRING的内容就是公钥PKCS#1格式的公钥数据,若显示数据,需要添加个偏移选项参数-strparse,在这里偏移值是17,添加后的执行结果如下:输出的数据与私钥文件中的n,e相同

openssl asn1parse -i -in rsa_public.pem  -strparse 17

0:d=0 hl=2 l= 72 cons: SEQUENCE
2:d=1 hl=2 l= 65 prim: INTEGER :B14A838D93A20FDEA12C68C883E43810EAE5A7482BC58D62D38ED485799D8159FCEF16E9BB13EFE323172DFBE9321001ABEFE9B76804099BCF23750404006F31
69:d=1 hl=2 l= 3 prim: INTEGER :010001

PKCS 介绍
PKCS即Public Key Cryptography Standards,公钥加密标准,一共有15个标准,编号从1到15。OpenSSL中RSA使用的是PKCS#1。PKCS#1定义了RSA的数理基础、公/私钥格式,以及加/解密、签/验章的流程。

openssl升级后RSA结构的变化
opensslv1.1.1版本之后RSA结构的变化
代码从openssl1.0.2转到openssl 3.0编译时报错:
error: dereferencing pointer to incomplete type ‘RSA’ {aka ‘struct rsa_st’}

不能通过RSA *rsa;
rsa->n去访问内部成员了。
在1.1.1之后,OpenSSL支持getter这样返回每个参数。

const BIGNUM *RSA_get0_n(const RSA *d);
const BIGNUM *RSA_get0_e(const RSA *d);
const BIGNUM *RSA_get0_d(const RSA *d);
const BIGNUM *RSA_get0_p(const RSA *d);
const BIGNUM *RSA_get0_q(const RSA *d);
const BIGNUM *RSA_get0_dmp1(const RSA *r);
const BIGNUM *RSA_get0_dmq1(const RSA *r);
const BIGNUM *RSA_get0_iqmp(const RSA *r);

#The RSA_size() and RSA_security_bits() functions were deprecated in OpenSSL 3.0.

非对称加密算法概述
非对称加密算法也称公开密钥算法,其解决了对称加密算法密钥分配的问题,非对称加密算法基本特点如下:

1、加密密钥和解密密钥不同

2、密钥对中的一个密钥可以公开

3、根据公开密钥很难推算出私人密钥

根据非对称加密算法的特点,可用户数字签名、密钥交换、数据加密。但是由于非对称加密算法较对称加密算法加密速度慢很多,故最常用的用途是数字签名和密钥交换。

目前常用的非对称加密算法有RSA, DH和DSA三种,但并非都可以用于密钥交换和数字签名。而是RSA可用于数字签名和密钥交换,DH算法可用于密钥交换,而DSA算法专门用户数字签名。

openssl 生成RSA代码

RSA* creatRSAkey()
{
    //r存放RSA密钥对
    RSA*r=RSA_new();
    //大数结构体 公钥质数 大质数
    //公钥(E,N)
    BIGNUM *e = BN_new(); //创建好了大数
    BN_set_word(e, RSA_F4); //公钥指数使用默认值 RSA_F4 65537,也可以使用随机值

    //生成私钥指数D和N
    RSA_generate_key_ex(r,
        512, //指定密钥长度为512bit
        e,
        NULL);
    return r;
}

rsa 加密填充模式说明

RSA加密常用的填充方式有下面3种:

1.RSA_PKCS1_PADDING 填充模式,最常用的模式

要求:
输入:必须 比 RSA 钥模长(modulus) 短至少11个字节, 也就是 RSA_size(rsa) – 11
如果输入的明文过长,必须切割, 然后填充

输出:和modulus一样长

根据这个要求,对于512bit的密钥, block length = 512/8 – 11 = 53 字节

2.RSA_PKCS1_OAEP_PADDING
输入:RSA_size(rsa) – 41

输出:和modulus一样长

3.for RSA_NO_PADDING  不填充

输入:可以和RSA钥模长一样长,如果输入的明文过长,必须切割, 然后填充

输出:和modulus一样长

跟DES,AES一样, RSA也是一个块加密算法( block cipher algorithm),总是在一个固定长度的块上进行操作。

但跟AES等不同的是, block length是跟key length有关的。

每次RSA加密的明文的长度是受RSA填充模式限制的,但是RSA每次加密的块长度就是key length。

需要注意:

假如你选择的秘钥长度为1024bit共128个byte:

1.当你在客户端选择RSA_NO_PADDING填充模式时,如果你的明文不够128字节

加密的时候会在你的明文前面,前向的填充零。解密后的明文也会包括前面填充的零,这是服务器需要注意把解密后的字段前向填充的零去掉,才是真正之前加密的明文。

2.当你选择RSA_PKCS1_PADDING填充模式时,如果你的明文不够128字节

加密的时候会在你的明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样。

对加密后的密文,服务器使用相同的填充方式都能解密。解密后的明文也就是之前加密的明文。

3.RSA_PKCS1_OAEP_PADDING填充模式没有使用过, 他是PKCS#1推出的新的填充方式,安全性是最高的,

和前面RSA_PKCS1_PADDING的区别就是加密前的编码方式不一样。

RSA 加解密接口
//@flen明文长度@from明文@to密文@rsa密钥@padding填充方式
int RSA_public_encrypt(int flen, const unsigned char *from,

                   unsigned char *to, RSA *rsa, int padding);

int RSA_private_decrypt(int flen, const unsigned char *from,

                    unsigned char *to, RSA *rsa, int padding);

openssl rsa 加解密代码

int RSAEncrypto(unsigned char *data, int datasize, RSA*r, unsigned char *outdata)
{
    //keysize=64字节512bit
    //输入数据大小=64-11=53
    int blocksize = RSA_size(r) - RSA_PKCS1_PADDING_SIZE;
    int outsize = 0;
    for (int i = 0; i < datasize; i += blocksize)
    {
        int ensize = blocksize;
        if (datasize - i < blocksize)
        {
            ensize = datasize - i;
        }
        int outoff = i + RSA_PKCS1_PADDING_SIZE * (i / blocksize);
        int ret = RSA_public_encrypt(ensize, data + i, 
      outdata + outoff, r, RSA_PKCS1_PADDING);
        if (ret < 0)
        {
            ERR_print_errors_fp(stderr);
        }
        outsize = outoff + RSA_size(r);
    }
    return outsize;
}

openssl rsa 解密代码

int RSAdecrypto(unsigned char *data, int datasize, RSA*r, unsigned char*outdata)
{
    int ensize = RSA_size(r);
    int outoff = 0;
    for (int i = 0; i < datasize; i += ensize)
    {
        int len=RSA_private_decrypt(ensize, data+i, 
          outdata+outoff, r, RSA_PKCS1_PADDING);
        outoff += len;
    }
    return outoff;
}

需要注意的是,在openssl3.0中 RSA_size被弃用。

RSA算法相关指令及用法
RSA虽然可以数字签名、密钥交换和数据加密,但是RSA加密数据速度慢,通常不使用RSA加密数据。所以最常用的功能就是数字签名和密钥交换,抛开数字签名和密钥交换的概念,实质上就是使用公钥加密还是使用私钥加密的区别。所以我们只要记住一句话:“公钥加密,私钥签名”。

公钥加密:用途是密钥交换,用户A使用用户B的公钥将少量数据加密发送给B,B用自己的私钥解密数据

私钥签名:用途是数字签名,用户A使用自己的私钥将数据的摘要信息加密一并发送给B,B用A的公钥解密摘要信息并验证

opessl中RSA算法指令主要有三个,其他指令虽有涉及,但此处不再详述。

指令 功能
genrsa 生成并输入一个RSA私钥
rsa 处理RSA密钥的格式转换等问题
rsautl 使用RSA密钥进行加密、解密、签名和验证等运算

openssl genrsa 使用说明

openssl help genrsa

Usage: genrsa [options]
Valid options are:
-help Display this summary
-3 Use 3 for the E value
-F4 Use F4 (0x10001) for the E value
-f4 Use F4 (0x10001) for the E value
-out outfile Output the key to specified file
-rand val Load the file(s) into the random number generator
-writerand outfile Write random data to the specified file
-passout val Output file pass phrase source
-* Encrypt the output with any supported cipher
-engine val Use engine, possibly a hardware device
-primes +int Specify number of primes

openssl 生成带密码加密的rsa 密钥

openssl genrsa -F4 -aes128 -passout pass:123456 -out rsa_private_crypt.pem 512

Generating RSA private key, 512 bit long modulus (2 primes)
..........+++++++++++++++++++++++++++
........+++++++++++++++++++++++++++
e is 65537 (0x010001)

cat rsa_private_crypt.pem 

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,7C229C265FAA4F314755944CCE15A817

5KijAfOakKOLI1IjluKIzH4TRLp5vxJtodKjnp3zhWbZ6tVLJEnDeiwEzcTrAuUH
0ruEc5SfOnZpSIl72Y8RmgtWyyjM0fBpAbmUT+r2gKQHURTw9qy74p0nEhujsxpu
oxrFUGjM/56oYTlCovMsz58fita/BZ3grdxDUFXGO78/s17hQyZV+z+7I/8VyUAJ
DvhkdiwcJ/HKP2ZDMyQzIat4Oa9p7r6Nk1tkfwq8FprCgiWSSA6O5e5kXEJ1y0Gl
oQKtvpaCKxksi5a7ngkrHgxdSOvgA9Kb4L3NSOaDW61svbRsU05IjCBQ73bP/7q4
zXhcI7i1AHcXy76sPkm0wy9kRJ/XzABqCq/4ZyqTqEhk0duebAGeMaVsCFVGn+6q
PGjhCsFP0ZPkmkregY+vRHS9tqC7E3Fopr/ZOoCSLAA3CNPoyz72YG+U5wZo8+TQ
-----END RSA PRIVATE KEY-----

openssl genrsa -F4 -aes128 -passout pass:123456 -out rsa_private_crypt.pem 1024

Generating RSA private key, 1024 bit long modulus (2 primes)
............................+++++
...+++++
e is 65537 (0x010001)

cat rsa_private_crypt.pem 

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,017AC0DBA662ADC280B9F6B3AE7BDAB6

6jpnXH93H44EwWGilh9MFiRwExfJE498j05HriqoL0W/ppoI4KZ4pqJfru5VxqJr
Y/FVMIlsDaphUGHuwRo7xy/V0YlywRNtvgWmEAayD5A527C/z9V8rdaunqJl0tW0
UGfevA1NBtsOuplpWLlH7wVF0Dixa8w5nAqphDc3x/F7NrrmAqqM3jWJt47FxrBV
8UA7a6h+vLb1l9/n34aji4GE8vyY42VQ2hnDMsJmy3SlbP9bqCQTUtQug5sslg3R
0MbNm//oT1Wo4N3BfmdPZkFPH9OPnNxtXZysmPVtvg6WBH9pn7LO0xQh884frM7w
etWqHnHu2G0pNYgTlsE5+6T9jbaNeYv5wJn96nT+kWUesdfcldeNXgolJL+rBrLz
RepAt5pS5R2TIMRriRxyeWgE8veLRsTecDuU7EnmBdQ8BEFFLU1QgD8sJ8i6cTs8
4RA1TpuLgzr1eRh07+QAjuDBi02inQ6bEUW5B8dlkp/48G7Pdcx0poo8PJ1ONK/k
FgLSm70LP7eagK1fxGCty5P6KOfALW69fiV3RlxfG6E3Yxx002weknIQB4qXuVwh
Qo1sLDKQah/xYu0CJ4g4DWt7eBrxjU7nrK1L2hc+i8wGTZkDr+Ww9vF/b1a4R8LZ
quNvGiIf89RQcx54+EyNtEE1LCUzMVUiT3MNrBoe4JlAykE+tnYqqDg2eYUW6DQz
h8QnwpuNyX3fYtmGDV+uB9YBRphIMiQSOxG9NYAe+S/NQyyM3g08AiKUZdyDpAmS
YnYzkc5YgxcRPQDGdiY8TmsKFAqo3IJi+tdlzXnYZS5QiXsTaiwvZznuhCreKBeN
-----END RSA PRIVATE KEY-----

openssl rsa 指令说明

openssl help rsa

Usage: rsa [options]
Valid options are:
-help Display this summary
-inform format Input format, one of DER PEM
-outform format Output format, one of DER PEM PVK
-in val Input file
-out outfile Output file
-pubin Expect a public key in input file
-pubout Output a public key
-passout val Output file pass phrase source
-passin val Input file pass phrase source
-RSAPublicKey_in Input is an RSAPublicKey
-RSAPublicKey_out Output is an RSAPublicKey
-noout Don't print key out
-text Print the key in text
-modulus Print the RSA key modulus
-check Verify key consistency
-* Any supported cipher
-pvk-strong Enable 'Strong' PVK encoding level (default)
-pvk-weak Enable 'Weak' PVK encoding level
-pvk-none Don't enforce PVK encoding
-engine val Use engine, possibly a hardware device

RSA密钥去除口令保护

openssl rsa -in rsa_private_crypt.pem -passin pass:123456 -out rsa_private_plain.pem
cat rsa_private_plain.pem 

-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCpP8Kf7qB6A8bW75FwQF2FWkbNbMwhaVcNKJUBV2B45FMPcDbo
QzuYb+mWG+/41hL5eHBguI5JHL2weftkZpaeG5rH4S2Uhq3CHGjaDjwaAIDG4gA/
ZL/0fw6Y8852qYgVjqyBCfvXEwDKuHBtJszCqW+ME5qAtgpodMl+QcMjtQIDAQAB
AoGBAJjHJJGoH5ZkyF4HHbs9bu5MgrM27cGPTHRlWLRAQqZ+PPgnrHjXD/nXs/y7
tVBjNfeaH58/mbknx5eBVUvZS0VvtLHgrrUvIZkfNeuSKmpS5L8QyYUm/NDnoNeO
zteMzILicWBiDdf6VawIulLs0pJGji8YKjP9iqzvziJ+RHAVAkEA2S/J8BeyFGcj
W7ITSCAK9GDN+RufG5a0/raSYzAg5W9wDHkL1GgvLbPidRRppAO50Cbbq+eTWl8m
GeamlJheswJBAMd+19r4aEy+9jr8kGnnMbDIktWmuVsomXOSGPUhvKZNak1pL8aK
gxdQEsKQVjxTYOwUcC1uJed/yOyKAoujp/cCQQCQaYdT3t2pVV8cZI8PoUbHcerj
Xetw08frqggybdkh1fRiRsaH6PKd6AOHKBiKV3PhJUVhy6yeJbBW/pf7LEmjAkBy
aMNAWC/wu5+ZCpmDssxjl1PmZZxttCX1Crd3dear9T/er1Fv6qXtq8VmgcKDDEpM
ehgvZbklP7qqNSfqj2vXAkEAgu0UbvbdyiCSSnmshOSL5DT+AagiWUHvA5u/BZOs
waYbf03A1v2U/p9+zzrCcgZv+gyT6Rmctum/voNO4X+QVw==
-----END RSA PRIVATE KEY-----

为RSA密钥增加口令保护

openssl rsa -in rsa_private_plain.pem -passout pass:123456 -out rsa_private_crypt0.pem

writing RSA key

cat rsa_private_crypt0.pem 

-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCpP8Kf7qB6A8bW75FwQF2FWkbNbMwhaVcNKJUBV2B45FMPcDbo
QzuYb+mWG+/41hL5eHBguI5JHL2weftkZpaeG5rH4S2Uhq3CHGjaDjwaAIDG4gA/
ZL/0fw6Y8852qYgVjqyBCfvXEwDKuHBtJszCqW+ME5qAtgpodMl+QcMjtQIDAQAB
AoGBAJjHJJGoH5ZkyF4HHbs9bu5MgrM27cGPTHRlWLRAQqZ+PPgnrHjXD/nXs/y7
tVBjNfeaH58/mbknx5eBVUvZS0VvtLHgrrUvIZkfNeuSKmpS5L8QyYUm/NDnoNeO
zteMzILicWBiDdf6VawIulLs0pJGji8YKjP9iqzvziJ+RHAVAkEA2S/J8BeyFGcj
W7ITSCAK9GDN+RufG5a0/raSYzAg5W9wDHkL1GgvLbPidRRppAO50Cbbq+eTWl8m
GeamlJheswJBAMd+19r4aEy+9jr8kGnnMbDIktWmuVsomXOSGPUhvKZNak1pL8aK
gxdQEsKQVjxTYOwUcC1uJed/yOyKAoujp/cCQQCQaYdT3t2pVV8cZI8PoUbHcerj
Xetw08frqggybdkh1fRiRsaH6PKd6AOHKBiKV3PhJUVhy6yeJbBW/pf7LEmjAkBy
aMNAWC/wu5+ZCpmDssxjl1PmZZxttCX1Crd3dear9T/er1Fv6qXtq8VmgcKDDEpM
ehgvZbklP7qqNSfqj2vXAkEAgu0UbvbdyiCSSnmshOSL5DT+AagiWUHvA5u/BZOs
waYbf03A1v2U/p9+zzrCcgZv+gyT6Rmctum/voNO4X+QVw==
-----END RSA PRIVATE KEY-----

RSA 修改密钥的保护口令和算法

openssl rsa -in rsa_private_crypt0.pem -passin pass:123456 -aes256 -passout pass:123456 -out rsa_private_crypt1.pem

writing RSA key

cat rsa_private_crypt1.pem 

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,E31EBA8056B42C56F1E6397799DA6DE1

pkaq3xxwHyp6iZ2yZuCmiVxeyYMXB3q6wZrBm0UyYRTHzMHp/xyGnvrFfkphG0LI
8zU1inq+r2XudGQCs5soRbRx2ipyrvPxuxQxkFL1WhmmWs7UfLaENRGJOnorfKR3
s2G4GmQZ3GZ8afR29knb/0sMp4nh2xiF7YmTxhrFxpcrqpDWrLgfYuVv9ssOzTX7
zvSRskrdpOKsODe94rTzZ2h98c7EEvYJvTmof1mtnfG1Ihbf0nX8oXeGUHWAwwff
A6izC/9UeUVTqid7EGCO6Jd5UuN8BmzSiG1Esf/PTve6cEYNwyK9jh4P8B8EYGA5
KvX1sI79ER7ONCWv8s1x+ls8z6EjPthXu8joblzzyiRBHZZRh6ZVIiVstEoj4ITQ
7AMpG/z0lBrj7QXNW/6DBdSkFwCDyhLJrmcCyUrt6vB567H5SEOK/29B9mY+m/N/
zoZ2jLv8qBcH/XxAEAND/ocu/h5M2GE3RYmeAjlG0Ut7R6BdwcDqr1LbGRbvjTWd
ahY9lsaPGRPWtAb0bjuryRbxCgRodJqtEB0zhXMPr+hbrqFIWrlR2yKH57ycnGVB
SbBwTS11KjkCfPbQ2oOuZwNKremb8ZgByMRsVfUHunFz+PRm45jOdZiXjJkEiwT2
BzJi3NvUVU6lGDhVW1fOvdaxyQCM8EXu8k9+zMFLJGtE5T5WLdA4SvalUdi3UIeF
oUomM2po52neQgPOTUaGimt1RxB51Anrhu1T7o0M8HuyX+1UfxohpYSWT1YBZJgs
qfn6xOf9x6ym2TaFozg1+yMmyGDILRAocz6dS8hImJZFGNp5YwgifWmW4eHmTMwX
-----END RSA PRIVATE KEY-----

openssl rsa 查看 rsa密钥相关参数

openssl rsa -in rsa_private_crypt1.pem -passin pass:123456 -text -noout

RSA Private-Key: (1024 bit, 2 primes)
modulus:

00:a9:3f:c2:9f:ee:a0:7a:03:c6:d6:ef:91:70:40:
5d:85:5a:46:cd:6c:cc:21:69:57:0d:28:95:01:57:
60:78:e4:53:0f:70:36:e8:43:3b:98:6f:e9:96:1b:
ef:f8:d6:12:f9:78:70:60:b8:8e:49:1c:bd:b0:79:
fb:64:66:96:9e:1b:9a:c7:e1:2d:94:86:ad:c2:1c:
68:da:0e:3c:1a:00:80:c6:e2:00:3f:64:bf:f4:7f:
0e:98:f3:ce:76:a9:88:15:8e:ac:81:09:fb:d7:13:
00:ca:b8:70:6d:26:cc:c2:a9:6f:8c:13:9a:80:b6:
0a:68:74:c9:7e:41:c3:23:b5

publicExponent: 65537 (0x10001)
privateExponent:

00:98:c7:24:91:a8:1f:96:64:c8:5e:07:1d:bb:3d:
6e:ee:4c:82:b3:36:ed:c1:8f:4c:74:65:58:b4:40:
42:a6:7e:3c:f8:27:ac:78:d7:0f:f9:d7:b3:fc:bb:
b5:50:63:35:f7:9a:1f:9f:3f:99:b9:27:c7:97:81:
55:4b:d9:4b:45:6f:b4:b1:e0:ae:b5:2f:21:99:1f:
35:eb:92:2a:6a:52:e4:bf:10:c9:85:26:fc:d0:e7:
a0:d7:8e:ce:d7:8c:cc:82:e2:71:60:62:0d:d7:fa:
55:ac:08:ba:52:ec:d2:92:46:8e:2f:18:2a:33:fd:
8a:ac:ef:ce:22:7e:44:70:15

prime1:

00:d9:2f:c9:f0:17:b2:14:67:23:5b:b2:13:48:20:
0a:f4:60:cd:f9:1b:9f:1b:96:b4:fe:b6:92:63:30:
20:e5:6f:70:0c:79:0b:d4:68:2f:2d:b3:e2:75:14:
69:a4:03:b9:d0:26:db:ab:e7:93:5a:5f:26:19:e6:
a6:94:98:5e:b3

prime2:

00:c7:7e:d7:da:f8:68:4c:be:f6:3a:fc:90:69:e7:
31:b0:c8:92:d5:a6:b9:5b:28:99:73:92:18:f5:21:
bc:a6:4d:6a:4d:69:2f:c6:8a:83:17:50:12:c2:90:
56:3c:53:60:ec:14:70:2d:6e:25:e7:7f:c8:ec:8a:
02:8b:a3:a7:f7

exponent1:

00:90:69:87:53:de:dd:a9:55:5f:1c:64:8f:0f:a1:
46:c7:71:ea:e3:5d:eb:70:d3:c7:eb:aa:08:32:6d:
d9:21:d5:f4:62:46:c6:87:e8:f2:9d:e8:03:87:28:
18:8a:57:73:e1:25:45:61:cb:ac:9e:25:b0:56:fe:
97:fb:2c:49:a3

exponent2:

72:68:c3:40:58:2f:f0:bb:9f:99:0a:99:83:b2:cc:
63:97:53:e6:65:9c:6d:b4:25:f5:0a:b7:77:75:e6:
ab:f5:3f:de:af:51:6f:ea:a5:ed:ab:c5:66:81:c2:
83:0c:4a:4c:7a:18:2f:65:b9:25:3f:ba:aa:35:27:
ea:8f:6b:d7

coefficient:

00:82:ed:14:6e:f6:dd:ca:20:92:4a:79:ac:84:e4:
8b:e4:34:fe:01:a8:22:59:41:ef:03:9b:bf:05:93:
ac:c1:a6:1b:7f:4d:c0:d6:fd:94:fe:9f:7e:cf:3a:
c2:72:06:6f:fa:0c:93:e9:19:9c:b6:e9:bf:be:83:
4e:e1:7f:90:57

openssl rsa 提取公钥中的模数(modulus)n

openssl rsa -in rsa_private_crypt1.pem -passin pass:123456  -pubout -out rsa_public.pem

writing RSA key

cat rsa_public.pem 

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpP8Kf7qB6A8bW75FwQF2FWkbN
bMwhaVcNKJUBV2B45FMPcDboQzuYb+mWG+/41hL5eHBguI5JHL2weftkZpaeG5rH
4S2Uhq3CHGjaDjwaAIDG4gA/ZL/0fw6Y8852qYgVjqyBCfvXEwDKuHBtJszCqW+M
E5qAtgpodMl+QcMjtQIDAQAB
-----END PUBLIC KEY-----

openssl rsa -in rsa_private_crypt1.pem -passin pass:123456  -noout -modulus 

Modulus=A93FC29FEEA07A03C6D6EF9170405D855A46CD6CCC2169570D289501576078E4530F7036E8433B986FE9961BEFF8D612F9787060B88E491CBDB079FB6466969E1B9AC7E12D9486ADC21C68DA0E3C1A0080C6E2003F64BFF47F0E98F3CE76A988158EAC8109FBD71300CAB8706D26CCC2A96F8C139A80B60A6874C97E41C323B5

openssl rsa 把pem格式转化成der格式

openssl rsa -in rsa_private_crypt1.pem -passin pass:123456 -outform der -aes256 -passout pass:123456 -out rsa_private_crypt.der

writing RSA key

hexdump -e '16/1 "%02X " "\n"' rsa_private_crypt.der 

30 82 02 5E 02 01 00 02 81 81 00 A9 3F C2 9F EE
A0 7A 03 C6 D6 EF 91 70 40 5D 85 5A 46 CD 6C CC
21 69 57 0D 28 95 01 57 60 78 E4 53 0F 70 36 E8
43 3B 98 6F E9 96 1B EF F8 D6 12 F9 78 70 60 B8
8E 49 1C BD B0 79 FB 64 66 96 9E 1B 9A C7 E1 2D
94 86 AD C2 1C 68 DA 0E 3C 1A 00 80 C6 E2 00 3F
64 BF F4 7F 0E 98 F3 CE 76 A9 88 15 8E AC 81 09
FB D7 13 00 CA B8 70 6D 26 CC C2 A9 6F 8C 13 9A
80 B6 0A 68 74 C9 7E 41 C3 23 B5 02 03 01 00 01
02 81 81 00 98 C7 24 91 A8 1F 96 64 C8 5E 07 1D
BB 3D 6E EE 4C 82 B3 36 ED C1 8F 4C 74 65 58 B4
40 42 A6 7E 3C F8 27 AC 78 D7 0F F9 D7 B3 FC BB
B5 50 63 35 F7 9A 1F 9F 3F 99 B9 27 C7 97 81 55
4B D9 4B 45 6F B4 B1 E0 AE B5 2F 21 99 1F 35 EB
92 2A 6A 52 E4 BF 10 C9 85 26 FC D0 E7 A0 D7 8E
CE D7 8C CC 82 E2 71 60 62 0D D7 FA 55 AC 08 BA
52 EC D2 92 46 8E 2F 18 2A 33 FD 8A AC EF CE 22
7E 44 70 15 02 41 00 D9 2F C9 F0 17 B2 14 67 23
5B B2 13 48 20 0A F4 60 CD F9 1B 9F 1B 96 B4 FE
B6 92 63 30 20 E5 6F 70 0C 79 0B D4 68 2F 2D B3
E2 75 14 69 A4 03 B9 D0 26 DB AB E7 93 5A 5F 26
19 E6 A6 94 98 5E B3 02 41 00 C7 7E D7 DA F8 68
4C BE F6 3A FC 90 69 E7 31 B0 C8 92 D5 A6 B9 5B
28 99 73 92 18 F5 21 BC A6 4D 6A 4D 69 2F C6 8A
83 17 50 12 C2 90 56 3C 53 60 EC 14 70 2D 6E 25
E7 7F C8 EC 8A 02 8B A3 A7 F7 02 41 00 90 69 87
53 DE DD A9 55 5F 1C 64 8F 0F A1 46 C7 71 EA E3
5D EB 70 D3 C7 EB AA 08 32 6D D9 21 D5 F4 62 46
C6 87 E8 F2 9D E8 03 87 28 18 8A 57 73 E1 25 45
61 CB AC 9E 25 B0 56 FE 97 FB 2C 49 A3 02 40 72
68 C3 40 58 2F F0 BB 9F 99 0A 99 83 B2 CC 63 97
53 E6 65 9C 6D B4 25 F5 0A B7 77 75 E6 AB F5 3F
DE AF 51 6F EA A5 ED AB C5 66 81 C2 83 0C 4A 4C
7A 18 2F 65 B9 25 3F BA AA 35 27 EA 8F 6B D7 02
41 00 82 ED 14 6E F6 DD CA 20 92 4A 79 AC 84 E4
8B E4 34 FE 01 A8 22 59 41 EF 03 9B BF 05 93 AC
C1 A6 1B 7F 4D C0 D6 FD 94 FE 9F 7E CF 3A C2 72
06 6F FA 0C 93 E9 19 9C B6 E9 BF BE 83 4E E1 7F
90 57

openssl rsa -inform der -in rsa_private.der -passin pass:123456 -modulus -noout

Modulus=B14A838D93A20FDEA12C68C883E43810EAE5A7482BC58D62D38ED485799D8159FCEF16E9BB13EFE323172DFBE9321001ABEFE9B76804099BCF23750404006F31

openssl rsa 把der格式转化成pem格式

openssl rsa -inform der -in rsa_private.der -passin pass:123456 -out rsa.pem

writing RSA key

cat rsa.pem

-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBALFKg42Tog/eoSxoyIPkOBDq5adIK8WNYtOO1IV5nYFZ/O8W6bsT
7+MjFy376TIQAavv6bdoBAmbzyN1BAQAbzECAwEAAQJAPz9p9xP3+NlffkxTXFoK
dl6WVzs0AmISI48M2iEsw3wS6auo09AUKg70mP0ueU/GlKsVY78CFzSfSLJUtGdY
AQIhANmovwa/oL5/HwS/IHRNk1r2ZvUnfPTc90zCW9EqZxFhAiEA0IViaiYkqcSw
IC+uTn+B87OLvGHLX4UKk1CRoMwQn9ECIEJPdJMbwl8G325UxBBqqd/mfYtmkl0P
DJBoDgz1PB1BAiEAtLdE6bYRBEkAU4S/TizXlTvAGQ2wUiJdXfrvmyoAJmECIBkM
IODUSpheA8692yYgQ6t/m8EEIVd2I7K8ebZXr2sc
-----END RSA PRIVATE KEY-----

openssl rsautl指令说明

rsautl用于密钥交换和数字签名。实质上就是使用RSA公钥或者私钥加密。

而无论是使用公钥加密还是私钥加密,RSA每次能够加密的数据长度不能超过RSA密钥长度,并且根据具体的补齐方式不同输入的加密数据最大长度也不一样,而输出长度则总是跟RSA密钥长度相等。RSA不同的补齐方法对应的输入输入长度如下表

数据补齐方式输入数据长度输出数据长度参数字符串
PKCS#1 v1.5少于(密钥长度-11)字节同密钥长度-pkcs
PKCS#1 OAEP少于(密钥长度-11)字节同密钥长度-oaep
PKCS#1 for SSLv23少于(密钥长度-11)字节同密钥长度-ssl
不使用补齐同密钥长度同密钥长度-raw
openssl help rsautl

Usage: rsautl [options]
Valid options are:
-help Display this summary
-in infile Input file
-out outfile Output file
-inkey val Input key
-keyform PEM|DER|ENGINE Private key format - default PEM
-pubin Input is an RSA public
-certin Input is a cert carrying an RSA public key
-ssl Use SSL v2 padding
-raw Use no padding
-pkcs Use PKCS#1 v1.5 padding (default)
-oaep Use PKCS#1 OAEP
-sign Sign with private key
-verify Verify with public key
-asn1parse Run output through asn1parse; useful with -verify
-hexdump Hex dump output
-x931 Use ANSI X9.31 padding
-rev Reverse the order of the input buffer
-encrypt Encrypt with public key
-decrypt Decrypt with private key
-passin val Input file pass phrase source
-rand val Load the file(s) into the random number generator
-writerand outfile Write random data to the specified file
-engine val Use engine, possibly a hardware device

使用rsautl进行加密和解密操作
/使用RSA密钥作为密钥进行加密,实际上使用其中的公钥进行加密/

openssl rsautl -encrypt -in plain.txt -inkey rsa_private_crypt1.pem -passin pass:123456 -out enc.txt

cat enc.txt |hexdump -C

00000000 12 41 bc 42 f3 b1 16 b4 3a 01 bb 11 ac f2 54 eb |.A.B....:.....T.|
00000010 4b 21 c5 64 65 df ac 80 28 7d 42 26 cc 6b 44 8f |K!.de...(}B&.kD.|
00000020 5d b0 00 1c 81 6f 77 14 5c 4c 7a 37 52 b6 c3 c7 |]....ow.Lz7R...|
00000030 39 df 16 12 58 a8 3b 1e 16 19 7e 57 80 94 43 b2 |9...X.;...~W..C.|
00000040 b5 7e 27 01 52 fc ef 46 53 a4 bc 98 1e a5 3e a0 |.~'.R..FS.....>.|
00000050 99 8f dd 52 bd e2 91 e8 7d 45 16 eb 2e 26 e5 42 |...R....}E...&.B|
00000060 e4 56 6f df e5 23 3d 88 55 f5 c2 c5 1b 2b 6f a3 |.Vo..#=.U....+o.|
00000070 9e a7 e2 fd ef c2 09 0b a5 e7 26 9b 88 64 c4 7e |..........&..d.~|
00000080
/使用RSA密钥作为密钥进行解密,实际上使用其中的私钥进行解密/

openssl rsautl -decrypt -in enc.txt -inkey rsa_private_crypt1.pem -passin pass:123456  -out plain1.txt

/使用公钥进行加密/

openssl rsautl -encrypt -in plain.txt -inkey rsa_public.pem -pubin -out enc1.txt

/使用RSA作为密钥进行解密,实际上使用其中的私钥进行解密/

openssl rsautl -decrypt -in enc1.txt -inkey rsa_private_crypt1.pem -passin pass:123456  -out plain1.txt

注意:相同的明文,使用密钥加密和公钥加密后的密文结果不一样?是因为rsa公钥加密的时候根据填充模式填充随机数,导致每次加密结果不同。默认使用的填充方式为-pkcs,可以使用-oaep -ssl -raw

使用rsautl进行签名和验证操作
/使用RSA密钥进行签名,实际上使用私钥进行加密/

openssl rsautl -sign -in plain.txt -inkey rsa_private_crypt1.pem -passin pass:123456 -out sign.txt

/使用RSA密钥进行验证,实际上使用公钥进行解密/

openssl rsautl -verify -in sign.txt -inkey rsa_private_crypt1.pem -passin pass:123456 -out replain.txt

当然也可以像上面的示例,只使用公钥,加上 -pubin 参数就可以了。

openssl PKCS 格式转换 命令
rsa private key To convert from PKCS#1 to PKCS#8:

openssl pkcs8 -topk8 -inform pem -in private_pkcs1.pem -outform pem -nocrypt -out private_pkcs8.pem

rsa private key To convert from PKCS#8 to PKCS#1:

openssl rsa -in private_pkcs8.pem -out private_pkcs1.pem

rsa public key To convert from PKCS#8 to PKCS#1:

openssl rsa -pubin -in public_pkcs8.pem -RSAPublicKey_out -out public_pkcs1.pem

rsa public key To convert from PKCS#1 to PKCS#8:

openssl rsa -RSAPublicKey_in -in public_pkcs1.pem -pubout -out public_pkcs8.pem

RSA私钥和公钥文件格式 (pkcs#1, pkcs#8)

RSA Public Key file (PKCS#1)
The RSA Public key PEM file is specific for RSA keys.

It starts and ends with the tags:

-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----

Within the base64 encoded data the following DER structure is present:

RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
}

Public Key file (PKCS#8)
Because RSA is not used exclusively inside X509 and SSL/TLS, a more generic key format is available in the form of PKCS#8, that identifies the type of public key and contains the relevant data.

It starts and ends with the tags:

-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

Within the base64 encoded data the following DER structure is present:

PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING
}
AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

So for an RSA public key, the OID is 1.2.840.113549.1.1.1 and there is a RSAPublicKey as the PublicKey key data bitstring.

RSA Private Key file (PKCS#1)
The RSA private key PEM file is specific for RSA keys.

It starts and ends with the tags:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

Within the base64 encoded data the following DER structure is present:

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

Private Key file (PKCS#8)
Because RSA is not used exclusively inside X509 and SSL/TLS, a more generic key format is available in the form of PKCS#8, that identifies the type of private key and contains the relevant data.

The unencrypted PKCS#8 encoded data starts and ends with the tags:

-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----

Within the base64 encoded data the following DER structure is present:

PrivateKeyInfo ::= SEQUENCE {
  version         Version,
  algorithm       AlgorithmIdentifier,
  PrivateKey      BIT STRING
}
 
AlgorithmIdentifier ::= SEQUENCE {
  algorithm       OBJECT IDENTIFIER,
  parameters      ANY DEFINED BY algorithm OPTIONAL
}

So for an RSA private key, the OID is 1.2.840.113549.1.1.1 and there is a RSAPrivateKey as the PrivateKey key data bitstring.

The encrypted PKCS#8 encoded data start and ends with the tags:

-----BEGIN ENCRYPTED PRIVATE KEY-----
BASE64 ENCODED DATA
-----END ENCRYPTED PRIVATE KEY-----

Within the base64 encoded data the following DER structure is present:

EncryptedPrivateKeyInfo ::= SEQUENCE {
  encryptionAlgorithm  EncryptionAlgorithmIdentifier,
  encryptedData        EncryptedData
}
 
EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
 
EncryptedData ::= OCTET STRING

The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo (see above).


2022年1月18日,鸦岗(一期)保障性住房项目施工总承包(标段二)项目正式封顶,标志着广州市首批共有产权房试点项目即将投入使用。
据悉,鸦岗保障房项目总建筑面积69215平方米,装配率达52.2%,最高层数为32层,计划建设3栋高层住宅及商业和配套公建裙楼。项目毗邻白云区重点规划的白云湖数字科技城内,该区域定位为“数字中国”实践高地、粤港澳大湾区协同创新试验区、广佛同城数字经济创新示范区。届时,该保障房项目周边环境将会有较大提升。
据项目所属的广州保障房建设和管理单位珠江住房租赁投资表示,项目定位为“广州市保障性住房建筑产业化项目”,实施装配式建筑,采用的预制构件为叠合楼板、装配式钢筋桁架楼承板、预制凸窗、预制轻质隔墙、装配式楼梯。较高的装配率使得项目现场整洁有序,在2021年9月,项目便成功举办了装配式施工技术技能提升服务活动,在次月举办广州市管项目安全生产专项提升工作现场会,项目的装配式混凝土施工技术及构件吊装安全管控理念均受到当地政府部门及媒体的高度关注与认可。

项目建设方中建四局表示,项目整体采用绿色建筑设计、海绵城市建筑设计理念与规划设计和创新技术等较为前沿的建筑技术,现已成功立项广东省建筑业新技术应用示范工程。此外,项目还利用BIM技术实现工程信息集成提高管理效率,配合爬架、铝模、水电预埋、塔吊前期深化,规避施工风险的同时提高了施工质量及效率。
鸦岗保障房项目预计在2023年国庆之前完成竣工交付,届时,两个标段加起来可为符合条件的刚需人群提供2000余套保障房,进一步缓解外来人才、家庭住房难的问题。

Referenced from:https://news.dayoo.com/guangzhou/202201/19/139995_54171939.htm