Tls

為什麼我在 TLS_RSA_WITH_AES_256_CBC_SHA 與 OpenSSL 通信的 FINISHED 片段中看不到 IV?

  • November 17, 2016

我正在實現一個 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 相同。

引用自:https://crypto.stackexchange.com/questions/41586