Implementation

TLS 1.2 客戶端完成消息包含什麼?

  • April 28, 2016

我正在實施 TLS 1.2,但我被困在客戶端完成的消息上。

我的問題是:使用 ECDHE_RSA_AES_128_GCM_SHA256 密碼套件時,TLS 1.2 中客戶端完成消息的大小和結構是什麼。

我搜尋了這個問題,有人說它的大小是 48 字節;進一步來說:

  • 12字節驗證數據
  • 1字節握手類型
  • 3字節校驗數據長度
  • 和 32 字節 MAC

這真的正確嗎?

我的意思是:根據RFC 5246完成的消息有{verify_data[verify_data_length]}verify_data = PRF(master_secret, finished_label, hash(handshake_messages). 此外,根據 RFC 5246 第 5 節PRF(secret, label, seed) = P_<hash>(secret, label+seed)P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed). 所以,當我使用 SHA256 計算 HMAC 時,verify_data它的大小是 32 字節。

結果,我對verify_data大小和完成的消息結構有點困惑。誰能幫助我理解這一點和/或以某種方式讓我走上正確的軌道?

rfc5246 7.4.9定義 verify_data

    PRF(master_secret, finished_label, Hash(handshake_messages))
       [0..verify_data_length-1];

注意第二行;這有效地將 PRF 輸出截斷為verify_data_length八位字節。它繼續說 verify_data 大小

取決於密碼套件。任何未明確指定 verify_data_length 的密碼套件的 verify_data_length 都等於 12。

ECDHE_RSA_AES_128_GCM_SHA256 在沒有明確指定的 rfc 5289 中定義,因此適用此預設值。

第二,某處有人錯了。GCM 和 CCM 密碼套件在(明文)記錄上沒有 HMAC,儘管流和“塊”(CBC)套件有;相反,AEAD 程序將身份驗證標籤添加到加密記錄中。將 6.2.3.3 與 6.2.3.1 和 6.2.3.2 進行比較。

Finished Message FOR TLS中,除非在密碼套件中另有說明,否則驗證數據的長度為 12 字節,因此在您的情況下,它的長度為 12 字節。它採用以下握手消息形式:

struct {
     HandshakeType msg_type;    /* handshake type */
     uint24 length;             /* bytes in message */
     select (HandshakeType) {
        ...
         case finished:            Finished;
     } body;
 } Handshake;

但是,由於問題原來是DTLS 而不是 TLS,因此將其修改為

struct {
    HandshakeType msg_type;
    uint24 length;
    uint16 message_seq;                               // New field
    uint24 fragment_offset;                           // New field
    uint24 fragment_length;                           // New field
    select (HandshakeType) {
      ...
      case finished: Finished;
    } body;
  } Handshake;

使用商定密碼套件的 PRF 創建完成的消息。創建握手消息後,您需要將其轉換為TLSCipherText結構,形式為

struct {
         ContentType type;
         ProtocolVersion version;
         uint16 length;
         select (SecurityParameters.cipher_type) {
             case stream: GenericStreamCipher;
             case block:  GenericBlockCipher;
             case aead:   GenericAEADCipher;
         } fragment;
     } TLSCiphertext;

但 DTLS 又是不同的

struct {
   ContentType type;
   ProtocolVersion version;
   uint16 epoch;                                     // New field
   uint48 sequence_number;                           // New field
   uint16 length;
   select (CipherSpec.cipher_type) {
     case block:  GenericBlockCipher;
     case aead:   GenericAEADCipher;                 // New field [sic]
   } fragment;
 } DTLSCiphertext;

在這裡,您使用的是ECDHE_RSA_AES_128_GCM_SHA256,它是一個 AEAD 密碼,因此它採用GenericAEADCipher的形式:

struct {
    opaque nonce_explicit[SecurityParameters.record_iv_length];
    aead-ciphered struct {
        opaque content[TLSCompressed.length];
    };
 } GenericAEADCipher;

在這裡,nonce_explicit 包含 8 個字節的 nonce,你將它與來自密鑰派生(4 個字節)的“固定 IV”結合起來,然後你得到 12 個字節的 IV 用於 AES-GCM 模式加密。(請注意,您只發送了 IV 的最後8 個字節)。

在這個結構中,aead-ciphered結果包括encryption output || authentication tag. 因此,您已通過將身份驗證標籤連接到加密消息來發送它。在完成消息的情況下,加密輸出認證標籤是完成消息的加密輸出。

最後,對於 TLS,密碼套件ECDHE_RSA_AES_128_GCM_SHA256來自伺服器端的預期完成消息應該如下所示:

16 --ContentType(hanshake)
03 03 --protocolVersion(tls 1.2)
00 28 -- message length(40)
 --finished message--
 00 00 00 00 00 00 00 00 --nonce_explicit. (8 byte) (this is write sequence number, for initial handshake this should be all zero)
 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx -- encrypted finished message. (16 byte) (Note that finished message is of length 16(1 byte finished message type + 3 byte handshake message length + 12 byte verify_data) )
 yy yy yy yy yy yy yy yy yy yy yy yy yy yy yy yy -- authentication tag. (16 byte) (this is also output of the encrption of finished message using AES-GCM)

但這對於 DTLS

16 -- type=handshake
fe fd -- version=DTLS1.2
nn nn -- epoch, 1 for the initial negotiation, more if renegotiation
00 00 00 00 00 00 -- seqnum, always zero because Finished is first after CCS
00 30 -- length=48
 (8 bytes) -- explicit nonce
 (24 bytes) -- encryption of Finished handshake message
 (16 bytes) -- authentication tag

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