通过OpenSSL命令来认识RSA算法

前言

OpenSSL是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。OpenSSL本身是一个基于C语言的库,但是它也提供一个名为openssl的可执行程序来实现它所具有的功能。
可以通过OpenSSL官网下载源码,Linux和MacOS系统configure一下,make一下就OK了,相信你会编译了。编译后源码根目录下生成libcrypto.a和libssl.a静态库,在apps目录下可以找到openssl可执行程序了。

RSA加解与解密

1. 生成RSA私钥

$ openssl genrsa -out PrivateKey.pem 1024

这里我们指定生成1024位的秘钥,默认使用的是2个质数,公钥指数e使用的65537。
查看生成的PEM文件

$ cat PrivateKey.pem 
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC1g48gTtj3MlqF+wG2RQwqgJXl9Cf+Ob0hQgyxXvJN6At4iLQK
hKPEWO/i5oJ6B8LuLDVTtc1dMrgbjjzqwGkxVdrnkpwdFuAwlkgOVh6at5mDhMS7
Mhl4ANuCCic9c19RLLCTvOgIbmTZtbXOgnA/7+Gg6b3pib6TCxn3PdV+FQIDAQAB
AoGBAIsQ/4BOSJajwo0x8W7XWenaWH404Ms7K3cmppjiWJxtsxQnEGGam+ocBbZ+
yup5tdRKlJTNDklgSYP7JxroTe6OuvHtAJ6yOtPl7v6JvVMgxEsl27DAvjy3gPqj
DPu8m7bKUZg4HmWQ5CcFSDsx3knbRSEILJXwn45E5ma1GUTFAkEA4854xt+nDKin
ps4f0nSGSnivsRt/wE8XZCoGqlUZgdxC767NW5ebsO7nksHh/2aJdfnS3GfkTpZL
XyoDAQobmwJBAMv6aVIBz+1M/mffWS0MAxyCQ9hGqPu0YAWgcnov4ydpKyggber0
bef6ee61FnTjHmFlq20+3M8p8AGG+m9HoA8CQBIXsuXwm17ZAj+wPTzEvmmpviJt
0a6fWXc+Eztx+M2khbhthKfSma3qu3+fYGidZyt0hPe2VJ6dNy0+s/BgMiMCQGsS
veqAbQdiHUGlaohM/+0dLEQBg37tRmJtwOoG7TSo7jCYJVrqiC73ur3lbS5acn4q
AnzMPNi6aPRESH3VmV0CQHpPekd3vBT3FtvsG3YI7zJuz4RVLhU4If4NxGr2qljN
8kivH/KmF8QkvW9x8MpB/EOKHm/+uwWTNbRL9DheOeE=
-----END RSA PRIVATE KEY-----

PEM格式的私钥第一行为-----BEGIN RSA PRIVATE KEY-----,最后一行为-----END RSA PRIVATE KEY-----,中间是私钥的Base64编码。

可以使用下面的命令查看私钥的细节

$ openssl rsa -in PrivateKey.pem -text -noout

2. 从私钥中提取公钥

$ openssl rsa -in PrivateKey.pem -pubout -out PublicKey.pem

通过私钥是可以很简单地计算出公钥,可以理解为私钥中包含公钥,但是通过公钥几乎是不可以计算出私钥的,如果能计算出就相当于RSA算法被破解了。。
查看生成的公钥

$ cat PublicKey.pem 
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1g48gTtj3MlqF+wG2RQwqgJXl
9Cf+Ob0hQgyxXvJN6At4iLQKhKPEWO/i5oJ6B8LuLDVTtc1dMrgbjjzqwGkxVdrn
kpwdFuAwlkgOVh6at5mDhMS7Mhl4ANuCCic9c19RLLCTvOgIbmTZtbXOgnA/7+Gg
6b3pib6TCxn3PdV+FQIDAQAB
-----END PUBLIC KEY-----

与私钥类似,PEM格式的公钥第一行为-----BEGIN PUBLIC KEY-----,最后一行为-----END PUBLIC KEY-----,中间是公钥的Base64编码。

3. 使用公钥进行加密

$ echo "HelloWorld" > plain.txt
$ openssl rsautl -encrypt -in plain.txt -pubin -inkey PublicKey.pem -out cipher.bin

加密后生成的是二进制数据文件,可以查看其内容

$ hexdump -C cipher.bin 
00000000  b4 61 69 f3 a0 70 f4 52  45 05 ac 8b 6f 11 3d 59  |.ai..p.RE...o.=Y|
00000010  87 cb aa 82 64 1b 99 bb  da b3 4e 0c 38 91 aa c5  |....d.....N.8...|
00000020  3d 07 5b 2f ae 88 bd 4e  5c 4c c0 c8 13 18 f7 ec  |=.[/...N\L......|
00000030  12 ba 4a c1 2d 29 d2 76  f8 09 2e b1 9a 11 43 3f  |..J.-).v......C?|
00000040  62 39 f0 96 45 5e a1 a7  41 f9 0b ea ce b0 87 81  |b9..E^..A.......|
00000050  6a db 9e 84 22 5f 86 a0  eb 79 e6 7b 56 99 9f 8d  |j..."_...y.{V...|
00000060  73 25 50 81 11 ac 10 e6  45 ee a4 cf d4 94 e0 49  |s%P.....E......I|
00000070  30 4d f4 4e 96 bd ae 44  83 98 7b 47 ca 81 b0 13  |0M.N...D..{G....|
00000080

前面说过可以理解为私钥中包含公钥,所以这一步也可以使用私钥进行加密:

$ openssl rsautl -encrypt -inkey PrivateKey.pem -in plain.txt -out cipher.bin2

4. 使用私钥进行解密

$ openssl rsautl -decrypt -inkey PrivateKey.pem -in cipher.bin -out plain2.txt

解密生成的明文为plain2.txt,与加密前的plain.txt对比就可以发现,解密完全正确。

$ md5sum plain.txt plain2.txt
6df4d50a41a5d20bc4faad8a6f09aa8f  plain.txt
6df4d50a41a5d20bc4faad8a6f09aa8f  plain2.txt

RSA签名与验证

1. 使用私钥进行签名

$ openssl rsautl -sign -inkey PrivateKey.pem -in plain.txt -out signature.bin

2. 使用公钥进行验证

$ openssl rsautl -verify -pubin -inkey PublicKey.pem -in signature.bin -out plain3.txt

查看验证后的文件plain3.txt,与签名前的一致。

$ md5sum plain.txt plain3.txt 
6df4d50a41a5d20bc4faad8a6f09aa8f  plain.txt
6df4d50a41a5d20bc4faad8a6f09aa8f  plain3.txt

RSA证书的生成与转换

1. 生成私钥

$ openssl genrsa -out PrivateKey.pem 1024

2. 创建证书请求文件

$ openssl req -new -key PrivateKey.pem -out RSACertReq.csr

此命令输完后出现交互式输入提示,按照要求输入相关的证书信息。有的字段可以为空。这个证书请求文件也是PEM格式的,可以直接查看其内容。

3. 生成证书并签名
$ openssl x509 -req -days 3650 -in RSACertReq.csr -signkey PrivateKey.pem -out RSACert.crt
$ openssl x509 -req -days 3650 -in RSACertReq.csr -signkey PrivateKey.pem -out RSACert.pem

指定3650为证书有效期天数,将用上面生成的私钥密钥和证书请求文件生成一个数字证书rsacert.crt。这个就类似公钥。
crt文件和pem文件都是X509 PEM格式的证书。

查看PEM证书内容

$ cat RSACert.pem
-----BEGIN CERTIFICATE-----
MIICkjCCAfsCFB9zgpOIxZmxWchPXSnCchseGRa7MA0GCSqGSIb3DQEBCwUAMIGH
MQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpamluZzEQMA4GA1UEBwwHQmVpamlu
ZzEQMA4GA1UECgwHTm9uLU9yZzENMAsGA1UECwwETm9uZTEUMBIGA1UEAwwLTGlt
aW5nIFNoYW8xHTAbBgkqhkiG9w0BCQEWDmxtc2hhb0AxNjMuY29tMB4XDTE4MDcw
NjA2NDgyMFoXDTI4MDcwMzA2NDgyMFowgYcxCzAJBgNVBAYTAkNOMRAwDgYDVQQI
DAdCZWlqaW5nMRAwDgYDVQQHDAdCZWlqaW5nMRAwDgYDVQQKDAdOb24tT3JnMQ0w
CwYDVQQLDAROb25lMRQwEgYDVQQDDAtMaW1pbmcgU2hhbzEdMBsGCSqGSIb3DQEJ
ARYObG1zaGFvQDE2My5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALWD
jyBO2PcyWoX7AbZFDCqAleX0J/45vSFCDLFe8k3oC3iItAqEo8RY7+LmgnoHwu4s
NVO1zV0yuBuOPOrAaTFV2ueSnB0W4DCWSA5WHpq3mYOExLsyGXgA24IKJz1zX1Es
sJO86AhuZNm1tc6CcD/v4aDpvemJvpMLGfc91X4VAgMBAAEwDQYJKoZIhvcNAQEL
BQADgYEAFzBYivdEE7zwZkmmMQuvQOF+adNUgCeU99RHcamIQL8aL26ZofC65CWt
VA3+Ql2AgkqEbdrRlK1grIEhzxiWcsggADAlP+nNOchtAasLrLSE9FqhI2vYkwMl
8964aBmdVGh+/lz8OBIMirkuGMV+jKj5NdWf43wKcVR4w1Y4UUc=
-----END CERTIFICATE-----

PEM证书第一行为-----BEGIN CERTIFICATE-----,最后一行为-----END CERTIFICATE-----,中间是公钥的Base64编码。

4. 转换格式:将PEM格式文件转换成DER格式

$ openssl x509 -outform der -in RSACert.crt -out RSACert.der

在有些场合下,公钥是不能使用base64编码的,上面的命令是将公钥的base64编码字符串转换成二进制数据X509 DER格式。

5. 导出PKCS#12证书文件

$ openssl pkcs12 -export -out RSACert.p12 -inkey PrivateKey.pem -in RSACert.crt

iOS好像需要用P12格式的证书,生成P12证书需要输入密码。

6. 查看证书

$ openssl x509 -in RSACert.der -inform der -noout -text
$ openssl x509 -in RSACert.pem -inform pem -noout -text
$ openssl pkcs12 -in RSACert.p12
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章