TLS 1.2实现求助:加密握手消息解密失败
TLS 1.2 AES-256-CBC-SHA握手消息解密失败的排查与修复
核心错误:算法套件误用
你混淆了TLS套件的哈希规则:TLS_RSA_WITH_AES_256_CBC_SHA使用SHA-1作为MAC和PRF的哈希算法,不是SHA256。代码里全程用hashes.SHA256(),导致生成的master secret、密钥块(MAC密钥、加密密钥)全部错误,这是解密失败的根本原因。
关键逻辑错误点
TLS记录解析错误
加密握手记录的结构是:5字节记录头(类型+版本+长度) + 16字节IV + 加密数据(含MAC、填充)。你没有剥离记录头就直接提取IV和密文,导致IV和密文包含记录头内容,解密后数据完全混乱。必须先跳过前5字节记录头,再取IV和密文。密钥块拆分错误
SHA-1的MAC密钥长度是20字节,AES-256密钥长度是32字节,正确的密钥块长度应为20*2 + 32*2 + 16*2 = 136字节,拆分逻辑也需对应调整:client_write_MAC_key = key_block[0:20] server_write_MAC_key = key_block[20:40] client_write_key = key_block[40:72] server_write_key = key_block[72:104]MAC验证缺失
TLS 1.2加密握手消息的处理顺序是解密 → 验证MAC → 去填充。你直接跳过MAC验证去填充,即使解密正确也会因数据完整性问题导致填充错误。客户端发送的消息需用client_write_MAC_key计算HMAC-SHA1,验证内容包含8字节消息序列号、记录类型、TLS版本、解密后数据(不含填充)。
修正后的代码示例
from hashes import SHA1 from hmac import HMAC # 预主密钥处理(这部分逻辑正确) premaster_secret = pow(encrypted_premaster, d, n).to_bytes(256, "big")[-48:] client_bytes = client_random.to_bytes(32, "big") server_bytes = server_random.to_bytes(32, "big") # 改用SHA-1生成master secret master_secret = prf(premaster_secret, b"master secret", client_bytes + server_bytes, SHA1(), 48) # 生成对应长度的密钥块 key_block = prf(master_secret, b"key expansion", server_bytes + client_bytes, SHA1(), 136) # 正确拆分密钥块 client_write_MAC_key = key_block[0:20] server_write_MAC_key = key_block[20:40] client_write_key = key_block[40:72] server_write_key = key_block[72:104] # 解析完整的TLS加密记录 encrypted_record = b"收到的完整加密握手记录字节流" record_type = encrypted_record[0] tls_version = encrypted_record[1:3] record_length = int.from_bytes(encrypted_record[3:5], "big") # 提取IV和密文 iv = encrypted_record[5:5+16] ciphertext = encrypted_record[5+16:5+record_length] # AES-CBC解密 cipher = AES.new(server_write_key, AES.MODE_CBC, iv) decrypted_data = cipher.decrypt(ciphertext) # 验证MAC(seq为当前握手消息的序列号,从0开始递增) seq_bytes = seq.to_bytes(8, "big") pad_length = decrypted_data[-1] # MAC计算输入:序列号+记录类型+版本+有效数据长度+有效数据 mac_input = seq_bytes + bytes([record_type]) + tls_version + (len(decrypted_data) - pad_length).to_bytes(2, "big") + decrypted_data[:-pad_length] calculated_mac = HMAC.new(client_write_MAC_key, mac_input, SHA1).digest() received_mac = decrypted_data[-20-pad_length:-pad_length] if calculated_mac != received_mac: raise ValueError("MAC验证失败") # 去除填充得到原始握手消息 decrypted_handshake = decrypted_data[:-pad_length] print(decrypted_handshake)
内容的提问来源于stack exchange,提问作者NIvrak Nivrak
相关产品推荐
相关产品推荐

