4、MD5与SHA-1哈希校验:摘要长度、碰撞风险、在固件签名中的应用场景

哈希校验,说白了就是给固件算一个「数字指纹」。你下载一个镜像,算一遍哈希值,跟官方公布的值比对——一致,说明文件没被篡改;不一致,那肯定有问题。MD5 和 SHA-1 是早年最常用的两种算法,但到今天,它们已经「廉颇老矣」。

我个人习惯把哈希算法分成两代:MD5/SHA-1 是第一代,SHA-256 及以上是第二代。为什么这么分?因为第一代算法在安全性上已经出现了致命伤。下面我带你逐个拆解。

4.1 摘要长度:为什么越长不一定越好?

MD5 输出 128 位,也就是 16 个字节,通常用 32 个十六进制字符表示。SHA-1 输出 160 位,20 个字节,40 个十六进制字符。你想想看,SHA-1 比 MD5 多了 32 位,理论上碰撞难度高了 2^32 倍——但这是理论。

算法 摘要长度 字节数 十六进制长度
MD5 128 位 16 字节 32 字符
SHA-1 160 位 20 字节 40 字符
SHA-256 256 位 32 字节 64 字符

在实际项目中,摘要长度直接影响存储和传输开销。比如在嵌入式 BootROM 里,存放一个 SHA-1 哈希需要 20 字节,而 MD5 只要 16 字节。对于只有几 KB 空间的 MCU,这 4 字节的差距可能就决定了能不能塞下校验逻辑。我记得有一次做 IoT 模块,Flash 只剩 2KB,硬是把 SHA-1 换成 MD5 才把校验代码装进去——当然,那是 2015 年的事,现在我不会这么干了。

4.2 碰撞风险:理论到现实的「翻车」

碰撞,就是两个不同的输入产生了相同的哈希值。MD5 的碰撞在 2004 年就被中国学者王小云团队攻破了。当时我在读研,看到那篇论文时整个人都愣住了——原来「不可能」的事真的发生了。

SHA-1 的碰撞来得晚一些。2017 年,Google 和 CWI 研究所联合发布了 SHAttered 攻击,生成了两个不同的 PDF 文件,SHA-1 值完全一样。嗯,这里要注意:SHA-1 的碰撞攻击需要 2^63 次计算,虽然比暴力穷举的 2^80 低了很多,但普通攻击者还是很难做到的。不过对于国家级对手或者有算力的攻击者来说,这已经不是问题了。

⚠️ 避坑指南: 我曾经在一个固件更新系统里看到,校验环节只用了 MD5。问开发人员为什么,他说「MD5 快啊」。没错,MD5 确实快,但攻击者可以构造一个恶意固件,让它跟合法固件的 MD5 值一模一样。你校验通过了,但烧进去的是后门代码。从那以后,我经手的项目一律禁止单独使用 MD5 或 SHA-1 做安全校验。

4.3 在固件签名中的应用场景

哈希算法在固件签名里扮演什么角色?简单说,签名不是对整个固件加密,而是对固件的哈希值加密。流程是这样的:

  1. 计算固件镜像的哈希值(比如 SHA-256)
  2. 用私钥对这个哈希值加密,得到签名
  3. 验证时,用公钥解密签名,得到原始哈希值
  4. 再算一遍固件的哈希值,比对两者是否一致

所以哈希算法的安全性直接决定了签名的可靠性。如果哈希算法能碰撞,攻击者就可以用同一个签名「套」到恶意固件上。

核心结论:
  • MD5 和 SHA-1 不能用于安全场景,只能做完整性校验(比如下载后检查文件是否损坏)
  • 固件签名必须使用 SHA-256 或更高强度的哈希算法
  • 如果兼容性要求必须用 SHA-1,至少搭配 RSA-2048 以上密钥,并做双重哈希(比如先 SHA-1 再 SHA-256)

下面这张图展示了哈希算法在固件签名流程中的位置:

哈希算法在固件签名流程中的位置 固件镜像 哈希计算 哈希值 私钥加密 数字签名 公钥解密 原始哈希值 比对结果 哈希算法的安全性决定了签名能否被伪造。MD5/SHA-1 已不满足安全要求。
💡 实战建议: 如果你在维护一个老项目,固件签名还在用 SHA-1,我建议你尽快升级。过渡方案可以是:在 BootROM 里同时支持 SHA-1 和 SHA-256 两种哈希,新固件用 SHA-256 签名,旧固件继续用 SHA-1。等所有设备都升级到新固件后,再彻底移除 SHA-1 支持。这个策略我在一个智能家居项目里用过,平稳过渡了 6 个月,没有出过问题。

最后说一句:哈希算法不是越「老」越可靠,恰恰相反。MD5 和 SHA-1 已经完成了它们的历史使命,现在该让它们退休了。在固件安全这件事上,别省那点计算时间——安全没有捷径。