为何维基百科的MD5碰撞字符串在PHP中无法生成相同哈希?
解决PHP中MD5哈希碰撞验证问题
你遇到的核心问题是直接将十六进制字符串作为普通文本计算MD5,而没有把十六进制转换为它代表的原始字节序列。维基百科上给出的碰撞示例是字节的十六进制表示,不是可直接计算哈希的字符串。
正确的实现步骤
获取正确的碰撞十六进制序列
你提到的目标哈希79054025255fb1a26e4bc422aef54eb4对应的两组碰撞字节的十六进制如下:- 第一组:
d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70 - 第二组:
d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70
- 第一组:
在PHP中转换并验证
使用hex2bin()函数将十六进制字符串转换为原始字节,再计算MD5哈希:// 两组碰撞数据的十六进制字符串 $hex1 = 'd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70'; $hex2 = 'd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70'; // 转换为原始字节 $data1 = hex2bin($hex1); $data2 = hex2bin($hex2); // 验证内容不同 var_dump($data1 !== $data2); // 输出 bool(true) // 计算并验证MD5哈希相同 $md5_1 = md5($data1); $md5_2 = md5($data2); var_dump($md5_1); // 输出 string(32) "79054025255fb1a26e4bc422aef54eb4" var_dump($md5_2); // 输出 string(32) "79054025255fb1a26e4bc422aef54eb4" var_dump($md5_1 === $md5_2); // 输出 bool(true)bash中验证的正确方式
如果要在bash中用md5sum验证,需要先将十六进制转换为字节文件:# 将十六进制转成二进制文件 echo -n "d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70" | xxd -r -p > file1.bin echo -n "d131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70" | xxd -r -p > file2.bin # 计算MD5 md5sum file1.bin file2.bin执行后会看到两个文件的MD5哈希完全一致。
关键说明
- 十六进制字符串是字节的表示形式,不是字节本身。比如十六进制的
d1是一个字节(十进制209),而作为字符串是两个字符'd'和'1',两者的MD5哈希完全不同。 - 必须用
hex2bin()(PHP 5.4+支持)将十六进制转换为原始字节,才能得到正确的碰撞哈希。
内容的提问来源于stack exchange,提问作者mehdi
相关产品推荐
相关产品推荐

