OpenSSL 之 RSA 相关命令学习笔记
2019獨角獸企業重金招聘Python工程師標準>>>
作者: Angus.Fenying <i.am.x.fenying@gmail.com>
日期: 2016-11-10 10:35 PM
本文介紹 OpenSSL 命令行進行 RSA 加密、解密、簽名、驗證的操作,但不涉及 RSA 算法原理解析,如有興趣,可以閱讀阮一峰的《RSA算法原理》。如果你只想知道 RSA 是什么,那么你只要記住:RSA 是一種加密算法,使用兩個密鑰,一個叫公鑰,一個 叫私鑰,使用公鑰加密的密文只有使用私鑰才可以解密,反之亦然。
Section 0: 生成隨機文件
由于 OpenSSL 創建密鑰文件是隨機生成的,因此有必要為之提供一份隨機數據源。
可以用 openssl 的 rand 命令創建一個 64MB 的隨機文件,保存為文件 randSrc.bin。
openssl rand -out ./randSrc.bin 67108864還可以使用 -base64 或者 -hex 兩個參數之一指定輸出格式為 BASE64 或者 HEX。
Section 1: 生成一個密鑰文件
小貼士:
這個命令的意思是:
- genrsa: 生成 RSA 密鑰文件。
- -aes256: 使用 AES256 算法加密生成的密鑰文件, 因此你需要輸入加密用的密碼(并記住)。
- -rand randSrc.bin 使用文件 randSrc.bin 作為隨機數來源。
- -out rsa.pem: 將生成的密鑰文件保存為 rsa.pem。
- 2048: 生成 2048 Bits 的 RSA 密鑰文件。
2048 Bits 是指 RSA 算法里 N 的長度,而不是說公鑰和私鑰都是 2048 Bits。
生成文件樣例:
-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,A6F8DD9D1D994363907C278CDF9B644CMfsPjXK6izOmmzMseG3M2aBKque20ao13+oFg/JdJtlCK0Vb11hLqq8h/ICnY3lI z1xuBKiXVykl521YumeTS6C+WtSkb71cy1u6lHBwdO44tWxklEqcl1sLYIWKyNaB VgKmS4BhfuUq8XlSt3LnuQT/BJWPP7+GUUaZG6/stMWAx+XBg9mMahxGCqo7aRcz ............... nLGRE27iklwGgSagaK40FDiSe69HcIBkHCUQYaYtXQzHNgjoQRkcotzo+vxM7XcL 5y5DHwA8IFwt9c5f14lxZ2cXF9p54JA3UMy+T7XggINDgBFuOPR/U3eBS2x6hHW6 eoGX+khw+s5atpNJaF4s6n2ViDseQsW+b8NfSdlX0j5f5xSasFcYgFsDZtBy/FqZ -----END RSA PRIVATE KEY-----這是一個密鑰文件,而不是一個純粹的私鑰文件,它包含了完整的密鑰信息,即是說,里面 既有公鑰也有私鑰。但是只能把它當成私鑰使用,公鑰部分請參考 Section 3。
Section 2: 去除密鑰文件的密碼
從 Section 1 生成的密鑰文件中提取沒有密碼的密鑰文件,以便給 Nginx 等服務器使用。
openssl rsa -in rsa.pem -out rsa_pri.pemSection 3: 根據私鑰生成公鑰
從 Section 1 生成的私鑰文件中提取公鑰文件。
openssl rsa -in rsa.pem -pubout -out rsa_pub.pemSection 4: 使用公鑰加密
RSA 加密和解密都是使用 openssl 的 rsautl 命令。
在 Section 3 里面生成了公鑰文件 rsa_pub.pem,下面使用它進行加密。 (先生成個數據文件)
echo 1234567890 > test.txt md5sum test.txt openssl rsautl \-encrypt \-in test.txt \-out test.secret \-pubin \-inkey rsa_pub.pem可以看到源文件 test.txt 的 MD5 值為 7c12772809c1c0c3deda6103b10fdfa0。
源文件 test.txt 只有 10 個字節大小,但是加密結果文件 test.secret* 居然有 256 字節(2048 位長),這是因為 RSA 密鑰是 2048 位長度的,而 RSA 加解密算法的操作 單位必須和密鑰長度一致。所以加密結果的大小一定和密鑰長度的一致。所以加密長度必須小于 密鑰長度 - 填充長度。
關于填充數據,默認使用 PKCS#1 v1.5 填充格式。
Section 5: 使用私鑰解密
在 Section 1 里面生成了密鑰文件 rsa.pem,下面使用它進行加密。
openssl rsautl -decrypt -in test.secret -out test.raw -inkey rsa.pem md5sum test.raw這里使用的是帶密碼的密鑰文件,因此需要輸入 AES 密碼先把密鑰文件解密出來。如果使用的是 Section 2 中生成的無密碼密鑰文件,那么則不需要輸入密碼了。
可以看到解密出來的文件 test.raw 的 MD5 值為 7c12772809c1c0c3deda6103b10fdfa0。
Section 6: 使用私鑰簽名
加解密是使用公鑰加密,私鑰解密,因為公鑰是公開的,私鑰是保密的。簽名和校驗則反過來, 私鑰簽名,公鑰校驗。
這里假設你要發送消息給你朋友,消息存在文件 test.txt 中,你已經擁有了你朋友的 公鑰文件 fr_pub.pem。
那么先用他的公鑰對文件進行加密:
openssl rsautl -encrypt -in test.txt -out test.msg -pubin -inkey fr_pub.pem得到了加密后的文件 test.msg,下面使用你自己的私鑰進行簽名。
先用 SHA256 算法生成文件的哈希校驗碼:
openssl sha256 -out test.hash test.msg得到了哈希校驗文件 test.hash,內容如下:
SHA256(test.msg)= ************************下面使用 RSA 私鑰對其進行簽名:
openssl pkeyutl \-sign \-in test.hash \-out test.sign \-inkey rsa_raw.pem或者
openssl rsautl \-sign \-in test.hash \-out test.sign \-inkey rsa_raw.pemRSA 私鑰簽名的實質是:使用 RSA 私鑰對數據的哈希校驗碼進行加密,這樣就可以用 對應的 RSA 公鑰解密得到數據的哈希校驗碼。
得到了簽名后的文件 test.sign,將它和 test.msg、rsa_pub.pem 一起發給你的朋友。
Section 7: 使用公鑰校驗
現在你的朋友收到了你發給他的三個文件,分別是:公鑰、簽名、消息。現在他怎么確定 消息是發給他的呢?當然是使用公鑰校驗啦。
首先,他同樣使用 openssl 生成文件 test.msg 的哈希校驗碼。
openssl sha256 -out test.hash test.msg然后使用你的公鑰文件對其進行校驗:
openssl pkeyutl \-verify \-in test.hash \-sigfile test.sign \-pubin \-inkey rsa_pub.pem如果校驗通過,則會看到提示:Signature Verified Successfully。
然后他再使用他的私鑰解密 test.msg 文件即可得到你發給他的消息了。
這里不使用 openssl rsautl -verify 命令,因為 rsautl 的 -verify 指令 僅僅是將輸入的文件用公鑰解密,但不與計算出來的哈希校驗碼進行比較,不如 pkeyutl 的 -verify 方便:
openssl rsautl \-verify \-in test.sign \-pubin \-inkey rsa_pub.pem前面說了,rsa.pem 里面既包含私鑰又包含公鑰,這里可以小小地證明一下。 直接使用 rsa_raw.pem 文件進行簽名校驗。
openssl pkeyutl \-verify \-in test.hash \-sigfile test.sign \-pubin \-inkey rsa_raw.pem如何,結果是不是一樣呢?
那么,問題來了。如果傳輸過程被人攔截了怎么辦?這就是下一篇文章的內容了。
轉載于:https://my.oschina.net/fenying/blog/786238
總結
以上是生活随笔為你收集整理的OpenSSL 之 RSA 相关命令学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python3随记——字符编码
- 下一篇: ZooKeeper安装配置