前言
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