1. 固件签名概述
各位同学好,我是老周。今天咱们开始聊固件签名。说实话,这个主题我讲了快十年,每次都有新感悟。先问大家一个问题:你写好的固件,凭什么让设备相信它是你写的?
嗯,这就是固件签名的核心价值。
1.1 为什么需要固件签名
我见过太多团队,固件编译完直接扔给产线烧录。设备跑得挺好,直到有一天——
某款智能门锁被爆出「万能密码」漏洞。后来一查,攻击者伪造了一个固件包,通过OTA通道推送给了设备。设备没做任何校验,直接升级。结果你懂的,门锁变「门开」。
这个案例我每次上课都会提。它说明一个道理:没有签名的固件,就像没贴封条的快递——谁都能拆,谁都能往里塞东西。
固件签名要解决三个核心问题:
- 完整性:固件在传输或存储过程中有没有被篡改?
- 真实性:这个固件到底是不是声称的发布者签发的?
- 不可否认性:发布者不能事后抵赖「我没发过这个版本」。
一句话总结:固件签名 = 给固件贴上一张「防拆封条」+「身份证」。
你可能会问:那用哈希校验不就行了?哈希能保证完整性,但保证不了真实性。攻击者可以同时替换固件和哈希值,你根本发现不了。签名用的是非对称密钥,私钥只有发布者持有,这才解决了信任问题。
1.2 签名与加密的区别
这个坑我踩过。刚入行那会儿,我以为签名就是加密的变种。后来被老架构师骂了一顿,才彻底搞明白。
咱们直接上对比表:
| 维度 | 加密 | 签名 |
|---|---|---|
| 核心目的 | 保证机密性,防止内容被偷看 | 保证完整性和真实性,防止内容被篡改 |
| 使用密钥 | 公钥加密,私钥解密 | 私钥签名,公钥验签 |
| 输出结果 | 密文(不可读) | 签名值(附加在原数据上) |
| 典型算法 | AES, RSA-OAEP, ECIES | RSA-PSS, ECDSA, Ed25519 |
| 能否恢复原文 | 能(解密后) | 不能(签名不隐藏数据) |
| 常见误解 | 「加密了就是安全的」 | 「签名就是加密的逆过程」 |
我的习惯:记住一句话——加密防偷看,签名防篡改。两个概念可以组合使用,但千万别混为一谈。
举个例子:你给朋友寄一封机密信。加密相当于把信装进保险箱,只有朋友有钥匙打开。签名相当于在信封上贴上你的指纹印章,朋友一看就知道是你寄的,而且信封没被拆过。
实际项目中,我经常看到有人把固件加密后当签名用。结果呢?设备升级时只检查了能不能解密,根本没验证固件来源。攻击者只要拿到一个合法固件,重新打包就能绕过校验。这种案例在IoT设备里比比皆是。
1.3 签名流程全景图
好了,理论讲完,咱们看看实际流程。下面这张图是我自己画的,涵盖了固件签名的完整链路:
流程其实不复杂,我拆成几步讲:
- 计算哈希:对原始固件做SHA-256哈希,得到一个固定长度的摘要。这一步是为了后续签名时效率更高——你想想看,签名一个256位的摘要,比签名几兆的固件快太多了。
- 私钥签名:用发布者的私钥对哈希值做签名运算,生成签名值。这个签名值本质上是对哈希值的「加密」,但用的是私钥。
- 打包分发:把原始固件、签名值、以及发布者的证书链打包在一起。证书链的作用是让设备能验证公钥的合法性。
- 设备验签:设备收到包后,先用证书链验证公钥是否可信,然后用公钥解密签名值得到哈希A,再自己计算固件的哈希B。如果A == B,说明固件没被改过,而且确实是私钥持有者签发的。
我曾经踩过的坑:有次做OTA方案,我把证书链直接硬编码在bootloader里。后来证书过期了,所有设备都无法升级。从那以后,我坚持用证书链动态验证,并且预留了证书更新机制。记住:证书会过期,密钥会轮换,设计时一定要考虑生命周期。
这里有个细节值得注意:签名流程中,固件本身是不加密的。如果你既想防篡改又想防泄露,那就先签名再加密。顺序很重要——先签名后加密,这样接收方可以先解密再验签,流程更清晰。
好了,第一章就到这里。内容不多,但都是基础中的基础。后面的章节咱们会深入每个环节,包括密钥怎么生成、怎么保管、证书链怎么设计、以及实际项目中的各种坑。慢慢来,不着急。