我正在开发python中的SSL解密器,但我在HMAC验证方面遇到了一些问题:
我已经提取了所有密钥环相关资料(客户端IV,MAC,密钥和服务器IV,MAC,密钥)。 当我收到第一个Application_Data消息(0x17)时,我能够解密它,但无法验证消息的完整性。
在RFC 2246(https://www.ietf.org/rfc/rfc2246.txt)上,告诉:
MAC生成为:
HMAC_hash(MAC_write_secret, seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment));
其中" +"表示连接。
SEQ_NUM 此记录的序列号。
散列 由指定的散列算法 SecurityParameters.mac_algorithm。
以此为例:
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"
在python中的HMAC_SHA256计算如下:
import hashlib
import hmac
hmac.new(<client_mac>,label+message,hashlib.sha256).digest()
我的问题是,我该如何计算标签? 正如RFC提到的那样,&#34; +&#34;表示串联,但串联什么
另外值得一提的是,TLSCompressed.version意味着:
在这个maillist(http://www.ietf.org/mail-archive/web/tls/current/msg14357.html)中,我发现了MAC值的澄清,
MAC(MAC_write_key, seq_num + TLSCipherText.type + TLSCipherText.version + length of ENC(content + padding + padding_length) + IV + ENC(content + padding + padding_length));
其中长度以通常的方式编码为两个字节。
但这对我没有意义,因为重新编码解密值以检查计算MAC是没用的。从最后一行&#34;其中长度以通常的方式编码为两个字节&#34; ,这是否意味着我应该使用
struct.pack(&#34; 1 H&#34;,长度)
然后删除&#34; \ x&#34;并使用此值?或者我应该在HEX中编码这个值然后连接它?
我有点迷失,因为RFC并不清楚如何使用值。
我一直在尝试几种组合(甚至是暴力强迫),但没有一种能够奏效,我希望你能照亮我的方式。
答案 0 :(得分:2)
好吧,在挖掘之后,我已经设法解决了这个问题。
RFC 5246,第6.2.3.1节(http://tools.ietf.org/html/rfc5246#section-6.2.3.1)
MAC生成为:
MAC(MAC_write_key, seq_num + TLSCompressed.type + TLSCompressed.version + TLSCompressed.length + TLSCompressed.fragment);
其中“+”表示连接。
但它没有指出数据大小,无论是表示格式(十六进制,字符串......)。
必须表示每个字段的方式如下:
SEQ_NUM:
struct.pack("!Q",seq_num)
TLSCompressed.type
struct.pack("!b",TLSCompressed.type)
TLSCompressed.version
struct.pack("!H",TLSCompressed.version)
TLSCompressed.length
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()