為什麼我在 TLS_RSA_WITH_AES_256_CBC_SHA 與 OpenSSL 通信的 FINISHED 片段中看不到 IV?
我正在實現一個 TLS 1.2 伺服器,與 OpenSSL 進行比較以確保我做對了,我注意到當密碼是 TLS_RSA_WITH_AES_256_CBC_SHA 時,IV 不在 FINISH 消息中。OpenSSL 從密鑰塊數據中獲取它,通過 PRF 從主密鑰派生。
我對 RFC ( https://www.rfc-editor.org/rfc/rfc5246#appendix-A.1 ) 的理解是 GenericBlockCipher 類型將 IV 作為片段數據的一部分。因此,AES_256_CBC 顯然是 GenericStreamCipher,而不是 GenericBlockCipher。但這不是附錄 C 所說的。誰能解釋為什麼 OpenSSL 沒有將 IV 放入 FINISHED v 1.2 消息中?
=====(確認我做對了)
我的 SERVER_HELLO 看起來像這樣:
00000000: 16 03 03 00 31 02 00 00 2D 03 03 6E 97 FF 27 00 ....1...-..n..'. 00000010: 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 ................ 00000020: 11 12 13 14 15 16 17 18 19 1A 1B 00 00 35 00 00 .............5.. 00000030: 05 FF 01 00 01 00 type = 'HANDSHAKE' tls_plaintext_maj = 3 tls_plaintext_min = 3 fragment = msg_type = 'SERVER_HELLO' body = server_version_major = 3 server_version_minor = 3 gmt_unix_time = 1855455015 random_bytes = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b' session_id = b'' cipher_suite = 'TLS_RSA_WITH_AES_256_CBC_SHA' compression_method = 0 extensions = [Container({'extention_type': 'RENEGOTIATION_INFO', 'extension_data': b'\x00'})]
OpenSSL 似乎很好,給我發了 CLIENT_KEY_EXCHANGE、CHANGE_CIPHER_SPEC 和這個 HANDSHAKE:
type = 'HANDSHAKE' tls_ciphertext_maj = 3 tls_ciphertext_min = 3 fragment = b"\x87E\x08\xf4\xc9A\xadw\xe8i\xdb\xd6\xcb\x9d\x82\xa9\xdd\xa9\xee\x8d\xaa\x94\xfd\xc3\xc9\xf5\x94\xb4\x1d\xb4@\xd6\xc1\x8d\x16\xf0\x05\xbb!\xeb\x14HY\xe0\xb9\xa9i0+\xda\n\xe1\x87'V\x16\x1b\xce\xc41\xe6\x81\xe5\xb3"
fragment
可以使用 AES256 解密,使用:client_iv = faaa0de35870f9041e40471b02d5dfd5 client_write_key = 702ca8bd8cc39a707b297f3ef164cb5c7a0f90f39a20fd86e3dfcdd2e01eeb62
這些密鑰是通過 PRF 和共享主密鑰在我這邊生成的,解密後它看起來是有效的(最後有 11 個 \0x0b 字節,這是預期的填充)。
In [8]: AES.new(bytes.fromhex('702ca8bd8cc39a707b297f3ef164cb5c7a0f90f39a20f ...: d86e3dfcdd2e01eeb62'), AES.MODE_CBC, bytes.fromhex('faaa0de35870f904 ...: 1e40471b02d5dfd5') ...: ) Out[8]: <Crypto.Cipher.AES.AESCipher at 0x99fada7208> In [9]: _.decrypt(b"\x87E\x08\xf4\xc9A\xadw\xe8i\xdb\xd6\xcb\x9d\x82\xa9\xdd ...: \xa9\xee\x8d\xaa\x94\xfd\xc3\xc9\xf5\x94\xb4\x1d\xb4@\xd6\xc1\x8d\x1 ...: 6\xf0\x05\xbb!\xeb\x14HY\xe0\xb9\xa9i0+\xda\n\xe1\x87'V\x16\x1b\xce\ ...: xc41\xe6\x81\xe5\xb3") Out[9]: b'\x1c\xe3<\x88\xf4\xc0\x98\xe3\x8f\xbf\xc9\xa9"\'\x1bq\x14\x00\x00\x0c]\x95\xb8+l\x10 \xad\x99\xd8\xe2\x16=\xbf\x9e{\xc7\xd5\xbdLm\x04n\xa6/\xfb \xfd\x8f\x96\x92\xe5\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b'
所以,我很確定我做對了。
謝謝…
沒有錯,只是解密CBC密文時,IV只會影響第一個塊的解密。第一個密文塊在解密第二個密文塊時將用作IV,第二個密文塊將在解密第三個密文塊時用作IV,以此類推。
因此,如果 IV 被添加到 CBC 密文之前,您實際上可以在解密密文時使用您想要的任意 IV,只要您也“解密”IV 並在呈現之前丟棄第一個解密文本塊純文字到下一層。
因此,您在問題中提供的任何資訊都與真正是 GenericBlockCipher 的密文片段不一致。
另請注意,在 TLS 1.2 中,GenericBlockCipher 片段的 IV 通常會隨機生成。特別是,它不能與 KDF 在 TLS 1.0 兼容模式下可選生成的 IV 相同。