本文大部分内容参考自:
http://blog.csdn.net/zhymax/article/details/7683925 《使用openssl命令剖析RSA私钥文件格式》
原作者博客: http://blog.csdn.net/zhymax
阿群做了整理
预备知识1:输出文件的编码格式
PEM编码(Privacy Enhanced Mail)
特点:纯文本文件, 以-----BEGIN 某某某-----
开头, 以-----END 某某某-----
结尾, 内容是 base64 编码.
备注:使用文本编辑器只能查看或复制文本而不能修改, 解码后底层的二进制数据结构仍需要借助openssl命令行工具才能解读.
PKCS#8格式是一种主流的密钥存储格式, 采用PEM编码方式来存储底层的ASN.1结构体二进制数据.
OpenSSL从1.0.0版本开始把PKCS#8格式作为默认的密钥文件存储格式.
存储密钥时可选加密口令格式或直接存储明文格式两种.
- PKCS#8 私钥加密格式, 以
-----BEGIN ENCRYPTED PRIVATE KEY-----
开头. 参见【练习1】 - PKCS#8 私钥非加密格式, 以
-----BEGIN PRIVATE KEY-----
开头. 参见【练习2】
打开此类纯文本格式的密钥文件, 通过标题行可以判断上述两种密钥文件是否需要输入解锁口令.
PEM编码虽然是纯文本, 但仍然要先还原回二进制数据之后才能取出 RSA 密钥的详细信息.
我们借助openssl命令行工具来查看一个RSA密钥包括的各个字段.
openssl命令入门
openssl命令由多个自命令组成, 需要掌握下列命令的调用参数
- 密钥的创建命令
openssl genpkey
- 单独提取公钥部分, 通过
openssl pkey
命令完成 - 输出密钥详细信息, 分别通过
openssl rsa
命令和openssl as1nparse
命令
前者只输出RSA密钥的数字, 后者逐层解析ASN.1
二进制数据结构体格式(一般不常用) - 常用的签名/校验签名/RSA加密/RSA解密: 分别使用
openssl rsautl
命令的-sign、-verify、-encrypt、-decrypt选项
【练习1】:
第一步、从命令行创建一个受口令保护的RSA密钥文件key1.pem,
选项-pass
指定解锁口令为1234
, 选项-aes128
指定解锁过程采用的是128位AES对称加密
openssl genpkey -algorithm RSA -out key1.pem -pass pass:1234 -aes128
第二步、从key1.pem中取出这个密钥的公钥部分, 另存为pub1.pem:
openssl pkey -in key1.pem -out pub1.pem -pubout
最后依次查看密钥的公钥信息和私钥信息
只查看公钥信息时不需要口令
openssl rsa -pubin -in pub1.pem -text -noout
openssl rsa -in key1.pem -text -noout
上述四个命令在阿群的Linux终端中执行时, 屏幕输出的结果依次如下:
<pre>$ openssl genpkey -algorithm RSA -out key1.pem -pass pass:1234 -aes-128-cbc
...........++++++
...................++++++
$ openssl pkey -in key1.pem -out pub1.pem -pubout
Enter pass phrase for key1.pem: (注: 此处提示我们输入解锁口令,即1234)
</pre>
打开两个输出文件key1.pem和pub1.pem(或从终端输入命令cat key1.pem
和cat pub1.pem
)
<pre>-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICzzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIGx4mWhx1mEcCAggA
MB0GCWCGSAFlAwQBAgQQfOdchM4ftSARZ9jZdS7F0wSCAoBb0aUTyrKlX5XULHhV
MXvAmP1AQNqj1Dos5So6UGHYi3y0/gbK6TsirJOquQ/MCEKD8F/4yqdWg8FgN/J5
epa3afmbRivkOwmthK/pl0vffoOGDqPndo/weTwpzBHAGRM7KmM2iURmU7wublQL
H9oec//jfVtjGVBshqpzf2Wkmt8svp+30itftKn5cUrHFwDQBhDqUO9OnxSg+DNt
Yyo2a4nxo6XncydEb+QoYQIM8jisGzcdkkw5rquLJlUQTDHTM8urIwwlqrwWp0iN
2P+F4AWfAKK+/lZRpLxdTCNa5wvgwwxh1TizKDnqcOO2jlVXxYyZycCabcnQUKFa
oMOjuOiiLGHi/1fDQYn2bLCtXg2DZQ6pvEOdqAsPgZFzKZv2VMUZ/knMG3zcC2pG
3ff7Tf6E3drLQTxR7MjyUKlDL3HM/NifQubwAbG2l/4xVrRHK13nMymtHC42eyuJ
Qi6EHUHAxnoHv+KgA4IKK7b3UwPFQqsgokLOLcslRZnsZtHrMsa+7qBUrJL9bvYB
54lC7VUXAB5OJv8kjHr9eRPY9TdP9vP9YsYh8nH7t2CdUH9r8iUyukhBmylhmjy6
JvMpfkjIHvHn3lHuxdt5s3hPLVh+bcaYHUClcHJPk8BbUZpeuFQT4UpBpauxLcHm
G96ElmLMAHRAVfGIuXUvusdJZNb3IMgpk6A7mXwVHvc9Mk3RO96bfKURGVIbyg9U
BT+bfGJ+rnJyWvc+yiG37KfYDVuBWw9tRhgbQ52CHHxxJgaHb3NQo9je3SMyvHs+
xieDQ7Vgk6QNd1e7Jckz2NuHEMhvxRDjR3smG0t5ExWyUXQL8hNWuRfRKzjc3FBR
GrUu
-----END ENCRYPTED PRIVATE KEY-----
</pre>
<pre>-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtBrMwAiE0yFYNm0MAIWtKf9Yj
h1LYZVniVsAaujzq77E5R8Wc04kOFT6mn/la4xn10fIw8tjkMT12MqWf/i9ShWjm
fFYGCQP0YUx/2F7ngt5gTvkCgCMT8l6UfXejnOsPNojmOh5FkDpqwqewZCRc87+1
kWvqeqRNGHuh98xeMwIDAQAB
-----END PUBLIC KEY-----
</pre>
<pre>$ openssl rsa -pubin -in pub1.pem -text -noout
Public-Key: (1024 bit)
Modulus:
00:ad:06:b3:30:02:21:34:c8:56:0d:9b:43:00:21:
6b:4a:7f:d6:23:87:52:d8:65:59:e2:56:c0:1a:ba:
3c:ea:ef:b1:39:47:c5:9c:d3:89:0e:15:3e:a6:9f:
f9:5a:e3:19:f5:d1:f2:30:f2:d8:e4:31:3d:76:32:
a5:9f:fe:2f:52:85:68:e6:7c:56:06:09:03:f4:61:
4c:7f:d8:5e:e7:82:de:60:4e:f9:02:80:23:13:f2:
5e:94:7d:77:a3:9c:eb:0f:36:88:e6:3a:1e:45:90:
3a:6a:c2:a7:b0:64:24:5c:f3:bf:b5:91:6b:ea:7a:
a4:4d:18:7b:a1:f7:cc:5e:33
Exponent: 65537 (0x10001)
</pre>
<pre>$ openssl rsa -in key1.pem -text -noout
Enter pass phrase for key1.pem: (注: 此处提示我们输入解锁口令,即1234)
Private-Key: (1024 bit)
modulus: --【模数n】
00:ad:06:b3:30:02:21:34:c8:56:0d:9b:43:00:21:
6b:4a:7f:d6:23:87:52:d8:65:59:e2:56:c0:1a:ba:
3c:ea:ef:b1:39:47:c5:9c:d3:89:0e:15:3e:a6:9f:
f9:5a:e3:19:f5:d1:f2:30:f2:d8:e4:31:3d:76:32:
a5:9f:fe:2f:52:85:68:e6:7c:56:06:09:03:f4:61:
4c:7f:d8:5e:e7:82:de:60:4e:f9:02:80:23:13:f2:
5e:94:7d:77:a3:9c:eb:0f:36:88:e6:3a:1e:45:90:
3a:6a:c2:a7:b0:64:24:5c:f3:bf:b5:91:6b:ea:7a:
a4:4d:18:7b:a1:f7:cc:5e:33
publicExponent: 65537 (0x10001) --【公钥指数e】
privateExponent: --【私钥指数d】
65:6c:57:fc:fc:42:9a:be:14:33:45:9f:b0:a3:e6:
50:75:3f:00:f4:82:0b:76:dd:89:5f:70:9c:3a:2f:
1b:48:05:8a:9e:17:a8:26:17:60:b9:f3:4f:98:d6:
82:00:3d:67:6a:f9:9c:d7:bd:6b:85:b1:91:67:7e:
ce:9a:21:02:36:95:45:51:47:8d:33:e0:1b:c2:eb:
f6:cc:4f:a8:3a:c3:8a:ff:13:79:a3:78:5f:26:24:
6d:76:d2:92:c7:88:27:2b:87:96:3a:0b:1e:fa:42:
2a:28:13:39:dd:29:d8:b3:eb:9d:8f:69:24:0d:1d:
f8:69:11:9c:25:a6:92:81
prime1: --【质数p】
00:e6:3f:33:6b:19:69:e8:4f:39:e6:b4:ac:90:83:
d4:49:b6:34:b6:08:7a:3f:f4:08:3b:f6:78:70:6d:
e8:44:00:62:59:a7:2b:0d:75:8b:94:4a:5a:b7:e4:
7e:c6:a4:1c:42:8b:9b:09:75:81:90:b5:34:0d:4f:
f6:73:f1:1c:2d
prime2: --【质数q】
00:c0:61:10:51:71:b7:c5:fd:05:4e:b8:47:c3:7e:
9a:75:1b:56:55:e2:66:67:ba:2b:9a:3c:0c:f1:35:
98:a0:b5:0d:8b:6e:3f:60:0a:c2:43:cb:24:56:b1:
e8:78:43:dd:8c:63:dc:4b:ff:05:ed:39:cd:9d:63:
b7:f1:04:ff:df
exponent1: --【d mod (p-1)】
00:87:50:d5:73:37:f8:5a:23:55:b0:14:b6:e6:27:
d3:f7:8e:31:e4:59:8f:1f:4e:d8:18:05:7e:3a:f5:
1c:ef:fa:19:d2:fe:bf:fa:a4:fe:67:24:5b:b4:7f:
81:52:54:d8:96:f3:5d:26:6d:fc:bb:83:03:18:5f:
ca:43:d1:8b:f1
exponent2: --【d mod (q-1)】
63:12:d9:cb:87:cc:03:db:bd:5b:00:0e:7d:40:7b:
1d:2a:39:f9:3b:02:50:13:11:97:79:ab:94:a1:6c:
7b:ff:21:fd:97:86:6d:d8:bc:99:1b:4a:18:97:c0:
c8:06:f3:56:f4:aa:a4:3c:ae:f9:af:d6:13:63:22:
7c:ae:7d:73
coefficient: --【(inverse of q) mod p 】
00:9e:75:2a:b4:46:ef:3c:37:bd:c5:d4:7c:f9:60:
89:af:05:55:3b:7c:47:a1:63:c0:cf:09:f9:47:7c:
8e:6a:91:3f:7e:55:dc:5e:47:3e:37:a0:78:16:3c:
de:17:9b:a3:67:a8:c8:a7:ee:d0:a0:99:b2:4a:d9:
5e:60:5e:71:6f
</pre>
【练习2】:
从命令行创建一个无口令保护的密钥key2.pem, 然后查看密钥信息.
<pre>openssl genpkey -algorithm RSA -out key2.pem
openssl rsa -in key2.pem -text -noout
</pre>
【练习3】: 使用前面自己创建的RSA密钥key1.pem对某个文件的哈希值进行数字签名
openss rsautl -sign -in "输入任意长文件的SHA1哈希值20字节.hex" -inkey key1.pem -out "签名值.sig"
(注: 计算长文件的SHA1哈希值可以使用命令sha1sum 某个长文件.txt
, 但它输出的是一个纯文本字符串, 不是我们要的二进制数据. 可借助其他hex编辑器)
【练习4】: 使用前面导出的公钥pub1.pem校验数字签名
openss rsautl -verify -in "签名值.sig" -pubin -inkey pub1.pem -out "输出签名前原始的哈希值20字节.hex"
下期预告
关于 ssh-keygen 的一点疑问
除了openssl之外, 还有好几种工具也可以生成RSA密钥文件, 包括OpenSSH的ssh-keygen
,GnuPG的gpg
等等.
其中 ssh-keygen 输出的RSA密钥文件的版本较旧, 这种比较旧文件格式不同于PKCS#8标准. 但是openssl支持这种旧版密钥格式.
网友评论