MD5哈希长度延展攻击原理
-
已知原始消息 ( m ) 和其对应的哈希值 ( h )。
-
选择额外数据 ( m’ )。
-
计算填充,使得填充后的消息长度满足长度模512等于448,并包含新消息的长度信息。
-
构造新消息 ( m + \text{填充} + m’ )。
-
计算新消息的哈希值 ( h’ )。
代码
import hashlib
import binascii
# 已知的消息 m 和对应的哈希值 h
m = b"2021130120211301202113012021130120211301"
h = binascii.unhexlify("f67ad8b1a25d84c8ed0558d95ee892ed")
# 额外数据 m'
additional_data = b";extra_data"
# 构造填充
# 填充格式为:0x80 + 0x00*(填充长度-1)+ 消息长度(以little-endian编码的64位整数)
original_length = len(m)
new_length = original_length + len(additional_data) # 新消息的长度,以字节为单位
padding_length = (64 - (new_length + 8) % 64) % 64 # 计算填充长度,使得填充后总长度模 512 等于 448
padding = b"\x80" # 添加比特 1
padding += b"\x00" * (padding_length - 1) # 添加 0
padding += new_length.to_bytes(8, byteorder='little') # 添加消息长度,占用 64 位
# 计算新消息的哈希值
# 这里我们不需要知道密钥k,只需要利用原始消息的哈希值和额外数据来计算新消息的哈希值
new_hash = hashlib.md5()
new_hash.update(padding + additional_data) # 更新哈希对象时,将填充和额外数据一起传递
forged_hash = new_hash.digest()
# 打印结果
print("Original message: ", m)
print("Additional data: ", additional_data)
print("Forged message: ", m + padding + additional_data)
print("Forged hash: ", binascii.hexlify(forged_hash))
# 检查是否与目标哈希值一致
if forged_hash == h:
print("Successfully forged a valid hash!")
else:
print("Failed to forge a valid hash.")
详细说明
- 首先写入消息m和哈希值h;自己写入额外添加数新消息据;运行代码后,会生成新的哈希值