如何让两个不同的输入生成相同的MD5哈希值?

admin 2025年5月19日11:59:46评论14 views字数 2397阅读7分59秒阅读模式

导语:2012年,一个名为"火焰"的超级病毒席卷中东,它之所以能长期潜伏,竟是利用了MD5算法的致命缺陷——允许不同的文件生成相同的"数字指纹"。今天我们就用"双胞胎DNA检测"的比喻,揭开哈希碰撞的神秘面纱。

一、MD5哈希算法简介

MD5(Message-Digest Algorithm 5)是一种广泛使用的哈希函数,能将任意长度的输入(如文件、字符串)转换为固定长度的128位(16字节)哈希值。其设计初衷是为数据生成唯一的“指纹”,用于校验文件完整性、密码存储等场景。然而,MD5的抗碰撞性(即找到两个不同输入生成相同哈希值的能力)早在2004年被中国学者王小云攻破,这使得它在安全敏感领域被逐步淘汰。

MD5算法就像一台精密验钞机,能将任意长度的数据压缩成128位的"数字指纹"。理想情况下:

  • 不同文件 → 完全不同哈希值 ✅
  • 相同文件 → 始终相同哈希值 ✅
如何让两个不同的输入生成相同的MD5哈希值?

MD5的核心原理

  1. 数据分块:输入数据被划分为多个64字节的块,若数据长度不足,则通过填充(Padding)补齐。
  2. 迭代压缩:每个块通过压缩函数处理,结合前一轮的中间哈希值(IHV),生成新的IHV。最终一轮的IHV即为MD5哈希值。
  3. 哈希生成:无论输入多大,最终输出均为128位的十六进制字符串(如18ef25b59079b7210a0040e48c5e5a5a)。

终端验证

# 计算文件MD5md5sum demo-file.docx# 输出:d41d8cd98f00b204e9800998ecf8427e

经典案例: Hello World vs Goodbye World

如何让两个不同的输入生成相同的MD5哈希值?
两个不同文件生成相同MD5

查看文件差异:

vimdiff GoodbyeWorld-colliding.exe  HelloWorld-colliding.exe
如何让两个不同的输入生成相同的MD5哈希值?
相同MD5文件差异对比

二、为什么两个不同的输入能生成相同的MD5?

1. 理论必然性:鸽巢原理

哈希函数的输出空间有限(MD5为种可能,128为MD5的比特位数),而输入无限。

如何让两个不同的输入生成相同的MD5哈希值?
鸽巢原理示意图

根据鸽巢原理,必然存在多个输入映射到同一个哈希值,这种现象称为哈希碰撞。具体来说:

  • 需要尝次 → 50%碰撞概率(生日攻击)
  • 现代计算机集群可在24小时内完成

2. 算法缺陷:碰撞生成效率高

MD5的压缩函数存在三个缺陷

  1. 消息分组处理漏洞(Merkle–Damgård结构缺陷);
  2. 非线性函数强度不足;
  3. 抗差分攻击能力薄弱。

以上缺陷使得攻击者可以快速构造碰撞。2004年,王小云团队提出一种方法,能在数小时内找到碰撞对。

此后,工具如md5collgen进一步简化了这一过程。

3. 实例验证:从图片到可执行文件

  • 图片碰撞:以下两个不同字符串的MD5均为253dd04e87492e4fc3471de5e776bc3d

    如何让两个不同的输入生成相同的MD5哈希值?
    两张不同图片:左侧为飞机,右侧为沉船
    如何让两个不同的输入生成相同的MD5哈希值?
    不同图片MD5值相同
  • 可执行文件碰撞:两个功能不同的程序(如一个正常、一个恶意)可通过修改特定字节生成相同MD5。

    如何让两个不同的输入生成相同的MD5哈希值?
    相同MD5的两款程序:文末有附件

三、如何生成MD5碰撞?

实验工具与原理

  • 工具md5collgen(SEED Labs提供)。
  • 核心思想:通过构造前缀(Prefix)和填充(Padding),生成两个不同的后缀(P和Q),使整体哈希相同。

实验步骤

任务1:生成两个内容不同但MD5相同的文件

  1. 输入前缀:创建一个长度不足64字节的文件(如prefix.txt)。
  2. 生成碰撞:运行命令md5collgen -p prefix.txt -o out1.bin out2.bin,工具会自动填充数据并生成两个哈希相同的文件。
  3. 验证:使用diffmd5sum检查文件差异与哈希值。

任务2:验证MD5的“后缀不变性”

若两个文件AB的MD5相同,则在其后追加相同内容(如task2),新文件A+task2B+task2的MD5仍相同。

任务3:生成行为不同的可执行文件

  1. 编写C程序:定义一个数组(如char xyz[128]),根据数组内容执行不同逻辑(如打印“正常”或“恶意”)。
  2. 编译与修改:编译程序后,用十六进制编辑器(如bless)定位数组位置,替换为md5collgen生成的碰撞块。
  3. 测试:运行两个程序,观察不同行为,但MD5相同。

四、真实世界攻击案例

案例1:Flame病毒(2012)

  • 攻击手法:伪造微软数字签名证书
  • 技术细节
    • 利用MD5碰撞生成合法证书的"影子版本"
    • 通过中间人攻击植入恶意代码

案例2:数字合同欺诈(2017)

  • 事件经过
    • A公司签署PDF合同后,对方通过碰撞生成有利版本
    • 两份合同MD5相同但条款金额不同

案例3:游戏外挂(2020)

  • 作弊手段
    • 制作与正版游戏文件MD5相同的外挂模块
    • 绕过反作弊系统的哈希校验

五、攻防演练:如何检测和防御?

攻击检测技术

  1. 差异位追踪

    defdetect_collision(file1, file2):    diff = bytes(a ^ b for a,b in zip(file1, file2))return sum(diff) > 128# 碰撞文件差异位通常集中
  2. 魔数校验:检查文件头部特征码
  3. 二次哈希:同时计算SHA-256值

防御方案

风险场景 解决方案 实施示例
文件完整性校验
弃用MD5,改用SHA3或采用多重校验(结合文件大小、SHA-1等其他哈希值综合验证)
sha3sum important_file.iso
数字签名
启用RSA-3072+SHA256
使用OpenSSL新版签名算法
密码存储
加盐哈希+慢哈希函数
argon2id -t 3 -m 12

参考资料

  • md5碰撞资料及经典样本.ziphttps://url25.ctfile.com/f/1848625-1505929171-8bf524?p=6277 (访问密码: 6277)

    如何让两个不同的输入生成相同的MD5哈希值?

(文末警示:本文实验仅供学习,恶意使用需承担法律责任)

关注我,带你用“人话”读懂技术硬核! 🔥

原文始发于微信公众号(全栈安全):如何让两个不同的输入生成相同的MD5哈希值?

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月19日11:59:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   如何让两个不同的输入生成相同的MD5哈希值?https://cn-sec.com/archives/4078623.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息