4. 固件包的签名与验签:非对称加密基础与数字签名流程
这一章,我们来聊聊OTA升级里最核心的安全防线——签名与验签。
你想想看,固件包从云端飞到设备端,中间要经过多少网络节点?万一被人篡改了怎么办?设备怎么知道收到的固件是官方发布的,还是黑客塞进来的恶意程序?
答案就是数字签名。说白了,就是给固件包盖一个「防伪章」。这个章谁也伪造不了,设备收到后一验就知道真假。
4.1 非对称加密基础:RSA 与 ECC
数字签名的底层依赖非对称加密。它跟咱们平时用的对称加密(比如AES)不一样,对称加密是「一把钥匙开一把锁」,加密解密用同一个密钥。而非对称加密,用的是「一对钥匙」——公钥和私钥。
- 私钥:自己死死藏好,谁也不能给。用来签名。
- 公钥:公开出去,谁都可以拿。用来验签。
目前主流的非对称算法就两个:RSA 和 ECC。我个人的习惯是,如果设备算力够、存储空间大,用 RSA 更省心;如果资源紧张,ECC 是更好的选择。
| 对比项 | RSA | ECC(椭圆曲线) |
|---|---|---|
| 安全性基础 | 大整数分解难题 | 椭圆曲线离散对数难题 |
| 密钥长度(同等安全强度) | 2048位 / 4096位 | 256位 / 384位 |
| 签名速度 | 较慢 | 较快 |
| 验签速度 | 较快 | 较慢 |
| 资源占用 | 高(内存、Flash) | 低 |
| 典型应用场景 | PC、服务器、网关 | IoT终端、MCU、智能卡 |
我的经验: 在资源受限的MCU上(比如Cortex-M0+,只有几十KB RAM),RSA 2048位的签名验签可能会跑不动。这时候 ECC 的 P-256 曲线几乎是唯一选择。我在一个智能门锁项目里就吃过这个亏,后来全切成了 ECC。
4.2 数字签名流程:到底是怎么签的?
数字签名不是直接把固件包扔给私钥加密就完事了。那样效率太低,而且固件包动辄几十MB,非对称加密根本算不过来。
真正的流程分两步走:先算摘要,再签摘要。
- 计算固件包的哈希值(摘要):用 SHA-256 这类哈希算法,把整个固件包算出一个固定长度的「指纹」。哪怕固件里改了一个 bit,这个指纹都会变得面目全非。
- 用私钥加密这个哈希值:加密后的结果,就是数字签名。
- 打包发布:把「固件包 + 数字签名 + 签名算法标识」一起发布出去。
设备端验签的时候,流程反过来:
- 用同样的哈希算法,计算收到的固件包的哈希值。
- 用公钥解密数字签名,得到原始的哈希值。
- 比较两个哈希值。如果一致,说明固件包没被篡改,确实是私钥持有者签发的。
核心要点: 签名保护的不是「内容不能被看到」,而是「内容不能被篡改」。固件包本身可以是明文传输的,但签名保证了它的完整性和来源可信。
下面这张图,把整个流程串起来了:
4.3 验签失败的处理策略:不能直接拒绝就完事
验签失败,说明固件包有问题——要么被篡改了,要么来源不对。但设备该怎么处理?直接扔掉?还是报个错就完事?
这里面的门道不少。我见过不少产品,验签失败后只是打印一条日志,然后继续执行升级。这等于把安全防线直接拆了。
正确的处理策略,应该分几个等级:
| 策略等级 | 处理方式 | 适用场景 |
|---|---|---|
| 严格拒绝 | 立即终止升级流程,删除已下载的固件包,恢复系统到升级前状态 | 所有OTA升级场景(默认策略) |
| 告警 + 重试 | 记录失败日志,尝试重新下载(最多3次),如果仍然失败则进入严格拒绝 | 网络不稳定可能导致传输损坏的场景 |
| 降级回滚 | 如果验签失败时系统已经部分升级,必须触发回滚机制,恢复到上一个可用版本 | 双分区(A/B)升级架构 |
| 安全锁定 | 连续多次验签失败(比如5次),锁定升级功能,需要管理员手动解锁 | 防止暴力攻击或恶意固件注入 |
避坑指南: 我曾经在一个项目中,设备验签失败后只是返回了一个错误码,上层应用没做任何处理。结果攻击者伪造了一个固件包,设备验签失败但继续运行了旧固件,看起来没问题。但攻击者利用这个漏洞,反复发送恶意包,最终导致设备进入了不可恢复的异常状态。记住:验签失败必须是一个「硬错误」,不能软处理。
4.4 公钥的存储:最容易被忽视的环节
签名算法再强,如果公钥被篡改了,一切白搭。攻击者只要把自己的公钥写进设备,然后用自己私钥签名的固件包就能通过验签。
所以,公钥的存储是整条安全链的「根信任」。我个人的建议是:
- 硬件隔离:把公钥烧录到芯片的一次性可编程(OTP)区域或安全元件(SE)中,软件无法修改。
- 代码固化:如果硬件不支持,至少把公钥编译到Bootloader的只读代码段,并加上写保护。
- 证书链:不要只存一个公钥,而是存一个根证书。固件包携带由根证书签发的次级证书,设备用根证书验次级证书,再用次级证书验固件。这样根证书可以永远不变,次级证书可以灵活更新。
我的习惯: 在量产时,我会把公钥的哈希值也存一份在设备里。每次验签前,先校验公钥本身是否被篡改。虽然多了一步操作,但能有效防止公钥被替换的攻击。
4.5 小结
数字签名是OTA升级安全的基石。RSA和ECC各有优劣,选型时要根据设备资源来定。签名流程的核心是「哈希 + 非对称加密」,验签失败必须严格处理,公钥存储必须安全可靠。