RSA 私鑰剖析
我正在學習OpenSSL和公鑰基礎設施,並對 RSA 密鑰的結構以及它與相應公鑰的關係感到好奇。
我可以使用 OpenSSL genrsa 命令生成一個私有 RSA 密鑰:
$ openssl genrsa -aes128 -out fd.key 2048 Generating RSA private key, 2048 bit long modulus ....+++ ...................................................................................... +++ e is 65537 (0x10001) Enter pass phrase for fd.key: **************** Verifying - Enter pass phrase for fd.key: ****************
我知道在生成私鑰時需要考慮三個因素:
- 算法
- 尺寸
- 密碼
在這種情況下,我使用 RSA 算法,2048 位大小,並使用AES-128 加密來加密密鑰。
我可以使用rsa 命令查看 RSA 密鑰的結構:
$ openssl rsa -text -in fd.key Enter pass phrase for fd.key: **************** Private-Key: (2048 bit) modulus: 00:b6:ae:03:fa:d5:ec:3d:7b:1e:a5:33:68:44:5f: [...] publicExponent: 65537 (0x10001) privateExponent: 1a:12:ee:41:3c:6a:84:14:3b:be:42:bf:57:8f:dc: [...] prime1: 00:c9:7e:82:e4:74:69:20:ab:80:15:99:7d:5e:49: [...] prime2: 00:c9:2c:30:95:3e:cc:a4:07:88:33:32:a5:b1:d7: [...] exponent1: 68:f4:5e:07:d3:df:42:a6:32:84:8d:bb:f0:d6:36: [...] exponent2: 5e:b8:00:b3:f4:9a:93:cc:bc:13:27:10:9e:f8:7e: [...] coefficient: 34:28:cf:72:e5:3f:52:b2:dd:44:56:84:ac:19:00: [...] writing RSA key -----BEGIN RSA PRIVATE KEY----- [...] -----END RSA PRIVATE KEY-----
我還可以使用rsa 命令查看公鑰:
$ openssl rsa -in fd.key -pubout Enter pass phrase for fd.key: **************** writing RSA key -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyOYm8hJCi3vKLaud2YTU O3glFfQUpJ6d4gXiWp//HkDQIvi2BFmvbUyHMh4XWLwPbmaX2dfJ5Aa8+ZIC9KCY y96Gmbw+v75RzxHq5iFLnZNFhYM2zkMvUUjJs/UqunOL1OoEiC06hb85SBepKtnE JUUKo/rtZ2Sj/pHvF0Wqu1hLyR3iOxdJb26+m2IhOy4wB3HI6FBcvrMd4Hmejpup skIRhTQXkV7XQ79yRCTS3ejiGoVvkPKzWxL+OFWOJTduXAk8McMLEozSGZll8bv7 jJUWLhmegvokKS2eLfA4B16yU59EgNbvuoG5doKUeV0LJ03Iiqv81nFB9SqEG/Xe VQIDAQAB -----END PUBLIC KEY-----
從十六進制維基頁面:
一個十六進制數字代表一個半字節(4 位),它是八位字節或字節(8 位)的一半。
我很好奇的一些事情:
- 哪些數字對應於 2048 位長度?它是素數,指數,係數……?
- 公鑰與私鑰有什麼關係?它是從數字中計算出來的,還是嵌入在私鑰中?
通過閱讀另一個答案,聽起來 2048 長度對應於模數。
但是,當我計算長度時,我得到 2056:
$ echo "00:b6:ae:03:fa:d5:ec:3d:7b:1e:a5:33:68:44:5f:d0:6a:0b:b5:87:31:80:a0:50:32:b0:7c:73:4b:f8:a2:03:91:89:c2:11:32:69:2e:13:90:71:f6:a9:48:21:00:c5:ad:1c:93:f0:21:27:ce:ca:15:04:53:30:c6:88:7b:45:c0:f2:01:d5:a7:9e:c1:c5:f2:ae:b0:7f:31:68:b7:3c:c3:62:13:eb:40:25:a9:3f:cd:81:90:9f:a1:3f:02:84:d8:6e:73:d2:5d:53:28:cc:97:35:f6:fa:5c:b7:dc:11:fb:60:08:1b:75:f7:74:dc:24:29:3e:ff:fb:ba:dc:77:2c:48:0d:3b:a1:7b:d9:9a:3d:52:7d:9a:d6:c1:f1:e7:46:df:be:75:b0:d2:0f:d2:1c:7b:25:57:94:33:8f:d5:b3:ee:7f:30:98:a9:06:25:b5:ab:b1:a6:ab:f9:f2:52:b8:e7:8f:87:5f:6d:96:36:67:47:38:4c:ef:29:c7:71:e4:07:7c:13:19:3a:e2:b4:3c:85:18:32:77:a6:98:0e:0d:b4:70:01:75:79:de:e9:83:c5:df:41:2f:69:f6:30:8d:13:29:84:9a:84:3a:c0:6a:4c:0d:bd:cd:9b:1e:93:de:8e:c9:a4:02:b7:0f:a2:96:45:ad:b8:3e:3a:d3:fd:4d" | tr ':' '\n' | wc -l 257
每行包含 2 個十六進制數字
257 * 2 = 514
每個數字包含 4 位
514 * 4 = 2056
加起來不應該是2048嗎?
哪些數字對應於 2048 位長度?它是素數,指數,係數……?
實際上只有模數 - 根據定義,密鑰大小與模數大小相同。對於使用 2 個素數的計算,素數通常是密鑰大小的一半(多素數 RSA 速度更快,並且在採用)。私有指數可能達不到完整的密鑰大小;它介於 0 和模數(不包括)之間。大小很有可能與字節模數相同或略小。
公鑰與私鑰有什麼關係?它是從數字中計算出來的,還是嵌入在私鑰中?
它是在密鑰對生成過程中計算出來的——其輸出既是私鑰也是公鑰。私鑰和公鑰共享相同的模數。通常由特定工具(如 OpenSSL)生成的私鑰包含公共指數,因此如果您有私鑰,您也可以提取/使用公鑰。
通常,公共指數是一個已知的小值——例如費馬的第四個素數:0x010001。但由於情況可能並非如此,因此公共指數(以及公共密鑰)通常不是從私鑰組件計算出來的。如果公共指數的大小與私有指數的大小相同,則您無法根據私鑰值計算它。
通過閱讀另一個答案,聽起來 2048 長度對應於模數。但是,當我計算長度時,我得到 2056 …
ASN.1 / DER 編碼的 INTEGER 值是有符號的,大端。由於始終設置正模數的最高有效位 - 假設密鑰大小可被 8 整除 - 它總是用填充字節設置為左填充模數
00
。否則,編碼將在所謂的二補碼編碼中表示負值- 最高有效位被視為符號位:0 表示正數表示,1 表示負數表示。所以模數八位字節的有符號編碼是 2048 + 8 位或 257 字節。但是模數的位長(在大多數程式 API 中被稱為)仍然是 2048。
請注意,OpenSSL 顯示了使用中國剩餘定理加速 RSA 計算所需的生成參數。原則上,私鑰也可以僅由私有指數和模數組成。