You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:30:32