Python TLS MAC消息验证

Python TLS MAC消息验证,python,macos,ssl,hmac,sha256,Python,Macos,Ssl,Hmac,Sha256,我正在用python开发SSL反密码,但在HMAC验证方面遇到了一些问题: 我已经提取了所有与密钥环相关的资料(客户端IV、MAC、密钥和服务器IV、MAC、密钥)。 当我收到第一条应用程序_数据消息(0x17)时,我能够对其进行解密,但无法验证消息的完整性 在RFC 2246()上,告诉: MAC生成为: HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type + TLSCompressed.ve

我正在用python开发SSL反密码,但在HMAC验证方面遇到了一些问题:

我已经提取了所有与密钥环相关的资料(客户端IV、MAC、密钥和服务器IV、MAC、密钥)。 当我收到第一条应用程序_数据消息(0x17)时,我能够对其进行解密,但无法验证消息的完整性

在RFC 2246()上,告诉:

MAC生成为:

   HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
                 TLSCompressed.version + TLSCompressed.length +
                 TLSCompressed.fragment));
  MAC(MAC_write_key, seq_num +
                        TLSCompressed.type +
                        TLSCompressed.version +
                        TLSCompressed.length +
                        TLSCompressed.fragment);
其中“+”表示串联

序号 此记录的序列号

散列 指定的哈希算法 SecurityParameters.mac_算法

以此为例:

Chosen cipher_suite is TLS_RSA_WITH_AES_256_CBC_SHA256

client_mac = "some random stuff"
message_type = 0x17
message_version = 0x0303
encrypted_message_length = 1184 (IV|Message|MAC|Offset)
decrypted_message_length = 1122 (removing IV, MAC and offset)
message = "some message of length 1122"
  • 客户端\u mac是从密钥环\u材料中提取的
  • 消息类型为0x17,因为作为应用程序数据消息类型,正确的值应为0x17
  • 消息版本为0x0303,因为它是TLS 1.2
  • 消息长度为1122,除去前面的IV、偏移量和MAC验证,消息的最终长度为1122
  • 序号为1,因为它是第一条消息
在python中,HMAC_SHA256计算如下:

import hashlib
import hmac
hmac.new(<client_mac>,label+message,hashlib.sha256).digest()
其中,长度按常规方式编码为两个字节

但这对我来说毫无意义,因为对解密值重新编码以检查计算MAC是没有用的。从最后一行“长度按照通常的方式编码为两个字节”,这是否意味着我应该使用

结构包(“!H”,长度)

然后删除“\x”并使用此值?或者我应该用十六进制编码这个值,然后连接它

我有点不知所措,因为RFC不清楚应该如何使用值


我已经尝试了几种组合(甚至是蛮力),但都不管用,我希望你能为我指点迷津。

好吧,经过一点探索,我终于解决了这个问题

RFC 5246,第6.2.3.1节()

MAC生成为:

   HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
                 TLSCompressed.version + TLSCompressed.length +
                 TLSCompressed.fragment));
  MAC(MAC_write_key, seq_num +
                        TLSCompressed.type +
                        TLSCompressed.version +
                        TLSCompressed.length +
                        TLSCompressed.fragment);
其中“+”表示串联

但它不指向数据大小,也不指向表示格式(十六进制、字符串…)

每个字段的表示方式如下所示:

import hashlib
import hmac
hmac.new(<client_mac>,label+message,hashlib.sha256).digest()
  • 序号:

    • 描述:一个整数计数器,从0开始,每接收或发送一帧都会递增。对于TCP会话,必须使用两个序号,一个用于服务器,另一个用于客户端,每次发送帧时递增
    • 表示法:此值必须表示为8字节的无符号Long
    • 表示示例: 结构包(“!Q”,序号)
  • TLS压缩类型

    • 描述:此字段从TLS记录层(加密的有效负载)提取。例如,如果是应用程序数据帧,则必须使用0x17
    • 表示:此值必须表示为带符号的字符,带有2个字节
    • 表示示例:
      struct.pack(“!b”,TLSCompressed.type)
  • TLSCompressed.version

    • 描述:此字段也从TLS记录层(加密的有效负载)中提取。例如,如果使用TLS1.2传输帧,则必须使用其十六进制表示0x0303
    • 表示法:此值必须表示为无符号短字符,包含2个字节
    • 表示示例:
      struct.pack(“!H”,TLSCompressed.version)
  • t压缩长度

    • 描述:此字段表示已解密的有效载荷的实际长度
    • 表示法:此值必须表示为无符号短字符,包含2个字节
    • 表示示例:
      struct.pack(“!H”,TLSCompressed.length)
  • TLSCompressed.fragment

    • 描述:此字段是实际**解密的有效负载。
    • 表示法:此值必须表示为字符串
作为一个python示例,我们前面的示例中的HMAC哈希如下所示:

hmac_digest = hmac.new(mac_secret,'',digestmod=hashlib.sha256)
hmac_digest.update(struct.pack('!QbHH',seq_num,TLSCompressed.type,TLSCompressed.version, len(decrypted)))
hmac_digest.update(decrypted)
hmac_digest.digest()

好吧,经过一段时间的挖掘,我终于解决了这个问题

RFC 5246,第6.2.3.1节()

MAC生成为:

   HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type +
                 TLSCompressed.version + TLSCompressed.length +
                 TLSCompressed.fragment));
  MAC(MAC_write_key, seq_num +
                        TLSCompressed.type +
                        TLSCompressed.version +
                        TLSCompressed.length +
                        TLSCompressed.fragment);
其中“+”表示串联

但它不指向数据大小,也不指向表示格式(十六进制、字符串…)

每个字段的表示方式如下所示:

import hashlib
import hmac
hmac.new(<client_mac>,label+message,hashlib.sha256).digest()
  • 序号:

    • 描述:一个整数计数器,从0开始,每接收或发送一帧都会递增。对于TCP会话,必须使用两个序号,一个用于服务器,另一个用于客户端,每次发送帧时递增
    • 表示法:此值必须表示为8字节的无符号Long
    • 表示示例: 结构包(“!Q”,序号)
  • TLS压缩类型

    • 描述:此字段从TLS记录层(加密的有效负载)提取。例如,如果是应用程序数据帧,则必须使用0x17
    • 表示:此值必须表示为带符号的字符,带有2个字节
    • 表示示例:
      struct.pack(“!b”,TLSCompressed.type)
  • TLSCompressed.version

    • 描述:此字段也从TLS记录层(加密的有效负载)中提取。例如,如果使用TLS1.2传输帧,则必须使用其十六进制表示0x0303
    • 表示法:此值必须表示为无符号短字符,包含2个字节
    • 表示示例:
      struct.pack(“!H”,TLSCompressed.version)
  • t压缩长度

    • 描述:此字段表示已解密的有效载荷的实际长度
    • 表示法:此值必须表示为无符号短字符,包含2个字节
    • 表示示例:
      struct.pack(“!H”,TLSCompressed.length)
  • TLSCompressed.fragment

    • 描述:此字段是实际**解密的pa