保留前缀与MD5碰撞差异段,移除后缀后能否维持两二进制MD5一致?
可行,但需严格保留碰撞对的完整状态依赖结构
首先明确结论:你的需求完全可行,之前修改后MD5不一致是因为操作破坏了MD5碰撞的状态连续性,而非需求本身不可能。
核心原理
MD5是迭代式哈希算法,每处理一个数据块都会更新内部状态。你手里的两个碰撞文件,是被构造为:
- 前缀内容完全相同,处理完前缀后,两个文件的MD5内部状态一致
- 中间碰撞段内容不同,但经过MD5压缩后,内部状态会再次回到完全一致的状态
- 后缀内容相同,基于一致的内部状态处理相同后缀,最终得到相同的MD5哈希
当你移除后缀时,只要保留完整的前缀+完整的碰撞段,两个文件处理到末尾时的MD5内部状态会一致,再加上相同的长度填充(因为两个截断后的文件长度完全相同),最终MD5哈希必然一致;而SHA256没有碰撞构造的特殊处理,因为碰撞段内容不同,SHA256哈希自然不同。
为什么之前操作失败?
你用dd、vim或十六进制编辑器修改后MD5不一致,大概率是以下原因:
- 截断位置错误:没有精确截断到碰撞段的结束位置,要么截断在碰撞段中间(破坏了碰撞构造的状态同步),要么两个文件的截断长度不一致(导致MD5最后的长度填充不同)
- 二进制文件编辑污染:vim会自动转换换行符、添加隐藏的EOF标记,部分十六进制编辑器保存时可能额外修改字节,破坏了原始文件的字节完整性
- dd参数计算错误:比如
count或skip值算错,导致两个文件保留的内容长度或范围不一致
正确操作步骤
- 定位碰撞段范围:
用二进制对比工具(比如xxd file1 > f1.hex、xxd file2 > f2.hex,然后diff f1.hex f2.hex)找到两个文件内容开始不同的偏移(碰撞段起始)和内容再次完全相同的偏移(碰撞段结束,即后缀起始)。 - 精确截断文件:
假设后缀从第N字节开始(偏移从0算的话是N-1),对两个文件执行完全相同的dd命令:
注意:必须保证两个文件的# 处理第一个文件 dd if=file1 of=file1-truncated bs=1 count=$((N-1)) # 处理第二个文件 dd if=file2 of=file2-truncated bs=1 count=$((N-1))count值完全一致,且N是碰撞段结束的精确位置。 - 验证结果:
执行以下命令验证:# 检查MD5是否一致 md5sum file1-truncated file2-truncated # 检查SHA256是否不同 sha256sum file1-truncated file2-truncated
注意事项
- 绝对不要用普通文本编辑器(如vim、Notepad)编辑二进制碰撞文件,避免字节污染
- 截断时必须保证两个文件的长度完全相同,MD5的长度填充是哈希计算的一部分,长度不同会直接导致哈希不同
- 如果无法准确定位碰撞段范围,可以尝试逐步缩短后缀长度,每次对比两个截断后的文件MD5,直到找到MD5仍一致的最短版本
内容的提问来源于stack exchange,提问作者dbecks7
相关产品推荐
相关产品推荐

