3、哈希算法基础:哈希函数特性、MD5/SHA家族对比、哈希在OTA中的应用

聊到OTA升级保护,哈希算法是绕不开的第一道门槛。说白了,哈希就是给数据算一个「指纹」。我刚开始接触嵌入式安全时,总觉得哈希就是个校验和,后来踩过坑才明白——它远比我想象的复杂。

3.1 哈希函数的四大核心特性

一个合格的哈希函数,必须满足四个基本特性。我习惯把它们记成「一固三抗」:

  • 固定输出长度:不管输入是1字节还是1GB,输出长度固定。比如SHA-256永远是256位。
  • 抗原像性:给定哈希值H,无法反推出原始数据M。这是哈希「单向」的本质。
  • 抗第二原像性:给定M1和H(M1),找不到另一个M2使得H(M2)=H(M1)。
  • 抗碰撞性:找不到任意两个不同的M1和M2,让H(M1)=H(M2)。

核心理解:哈希不是加密。加密可逆,哈希不可逆。在OTA中,我们利用哈希来保证固件包的完整性——只要固件被篡改,哈希值就会变。

我在一个车机项目里遇到过这样的问题:有人试图用MD5碰撞来伪造固件包。嗯,这就是抗碰撞性失效的典型案例。后面我们会细讲。

3.2 MD5与SHA家族:一场关于安全的进化史

哈希算法家族里,MD5和SHA系列是最常见的。我画了一张对比图,帮你快速建立整体认知:

哈希算法家族对比总览 MD5(128位) ❌ 已破解(2004年) ❌ 碰撞攻击仅需秒级 ⚠️ 仅用于非安全校验 SHA-1(160位) ❌ 已破解(2017年SHAttered) ❌ 需约10万美金算力 ⚠️ 逐步淘汰中 SHA-2(224/256/384/512) ✅ 当前工业标准 ✅ 无实际攻击 ✅ OTA首选 OTA升级中的哈希选型建议 • 新项目:强制使用SHA-256或更高,不要考虑MD5/SHA-1 • 存量项目:如果还在用MD5做签名校验,请立即升级 • 性能敏感场景:SHA-256在Cortex-M4上约50-80μs/KB,可接受 • 安全等级:SHA-256提供128位安全强度,SHA-512提供256位

3.3 详细对比:MD5 vs SHA-1 vs SHA-2 vs SHA-3

光看总览还不够,我们深入对比一下这几个算法的关键参数。这张表我建议你收藏,选型时直接翻出来看:

算法 输出长度 安全强度 速度(相对) 状态 OTA适用性
MD5 128位 < 18位 最快 已破解 ❌ 不推荐
SHA-1 160位 < 63位 较快 已破解 ❌ 不推荐
SHA-256 256位 128位 中等 安全 ✅ 推荐
SHA-384 384位 192位 较慢 安全 ✅ 可选
SHA-512 512位 256位 慢 安全 ⚠️ 资源充足时
SHA-3 可变 同SHA-2 较慢 安全 ⚠️ 新项目可考虑

我的经验:在嵌入式OTA中,SHA-256是「甜点」选择。它提供了足够的安全强度,计算速度在大多数MCU上可以接受。我曾经在一个STM32H7项目上实测,SHA-256处理1MB固件只需要约80ms——完全够用。

3.4 哈希在OTA中的三个关键应用

哈希在OTA升级中不是孤立存在的,它贯穿了整个流程。我把它总结为三个核心场景:

场景一:固件完整性校验

这是最基础的应用。固件包下载完成后,设备计算本地哈希值,与服务器下发的哈希值对比。不一致就说明固件被篡改或传输出错。

// 伪代码:固件完整性校验
uint8_t received_hash[32];  // 从服务器获取的SHA-256哈希
uint8_t computed_hash[32];  // 本地计算

sha256_init(&ctx);
sha256_update(&ctx, firmware_buffer, firmware_size);
sha256_final(&ctx, computed_hash);

if (memcmp(received_hash, computed_hash, 32) == 0) {
    // 固件完整,继续升级
} else {
    // 固件被篡改,拒绝升级
    report_error(ERROR_HASH_MISMATCH);
}

场景二:数字签名的哈希预处理

签名算法(如RSA、ECDSA)不能直接对固件签名——固件太大,性能扛不住。正确的做法是:先对固件算哈希,再对哈希值签名。这就是「哈希+签名」的经典组合。

关键点:签名验证的是哈希值,不是原始固件。所以哈希算法的安全性直接决定了整个签名体系的安全性。如果哈希能碰撞,签名就形同虚设。

场景三:增量升级的块哈希校验

在差分/增量升级中,固件被分成多个块。每个块都有自己的哈希值。设备只下载变化的块,然后逐块校验。这样做的好处是:

  • 节省带宽:只传输变化的部分
  • 局部容错:某个块校验失败,只需重传该块,不用全量重下
  • 并行验证:多块可以同时计算哈希,提升速度

我曾经踩过的坑:在一个车机项目中,我们用了MD5做块哈希校验。结果发现攻击者可以构造两个不同的块,但MD5值相同。虽然概率极低,但在安全审计时被一票否决。后来全部换成SHA-256,审计才通过。所以我的建议是——别在安全相关的场景里用MD5,哪怕只是做完整性校验。

3.5 嵌入式环境下的哈希选型建议

选哈希算法不能只看安全强度,还得考虑嵌入式平台的限制。我整理了几个实际考量点:

  • 算力:Cortex-M0+跑SHA-256会比较吃力,可以考虑硬件加速或选择SHA-224
  • 内存:SHA-512需要更大的上下文结构(约200字节),在RAM紧张的芯片上要注意
  • 功耗:电池供电设备,哈希计算时间越长,功耗越高。SHA-256是较好的平衡点
  • 硬件加速:很多现代MCU(如STM32L5、NXP i.MX RT)内置哈希硬件引擎,能大幅提升速度

我的习惯:新项目一律用SHA-256。如果芯片支持硬件SHA-256加速,那就更好了。对于资源极度受限的场景(比如8位MCU),可以考虑SHA-224,但不要降级到MD5。