通過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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章