3、固件加密基础:对称加密与非对称加密、哈希函数、数字签名
加密这东西,说白了就是给固件穿上一件防弹衣。我见过太多产品,固件直接明文存在 Flash 里,拿个烧录器一读,代码全裸奔。嗯,这章咱们就把加密的底牌翻出来看看。
3.1 对称加密:又快又简单,但钥匙怎么给?
对称加密,就是加密和解密用同一把钥匙。你想想看,就像你家大门,锁门和开门用的是同一把钥匙。优点是快,特别快。我在做一款 IoT 网关时,固件包 8MB,用 AES-128 加密,整个流程不到 200 毫秒。
常用的对称加密算法,我列个表,你一看就明白:
| 算法 | 密钥长度 | 分组大小 | 我的评价 |
|---|---|---|---|
| AES | 128 / 192 / 256 bit | 128 bit | 工业标准,首选 |
| DES | 56 bit | 64 bit | 别用了,太老 |
| 3DES | 112 / 168 bit | 64 bit | 慢,不推荐 |
| SM4 | 128 bit | 128 bit | 国标,国内项目必备 |
我个人习惯,固件加密首选 AES-128-GCM。为什么?GCM 模式自带认证,能检测数据是否被篡改。我在项目中遇到过,有人用 AES-ECB 模式加密固件,结果被攻击者通过重放攻击搞崩了系统。ECB 模式,同一个明文块会生成同一个密文块,这太危险了。
3.2 非对称加密:钥匙分两把,一把公开一把私藏
非对称加密,加密用公钥,解密用私钥。公钥可以公开,私钥必须保密。这解决了对称加密的「钥匙配送」难题。你想想看,如果设备要跟服务器通信,对称加密的密钥怎么安全地传给设备?用非对称加密来协商,就安全多了。
常见的非对称加密算法:
- RSA:老牌算法,2048 位以上才安全。但慢,真的很慢。我在嵌入式设备上做过测试,RSA-2048 签名一次要 50 毫秒左右。
- ECC(椭圆曲线):比 RSA 快,密钥更短。256 位的 ECC 安全性相当于 3072 位的 RSA。我建议新项目优先考虑 ECC。
- SM2:国标椭圆曲线算法,国内项目必须支持。
非对称加密在固件安全里,主要干两件事:
- 密钥交换:比如 ECDH,双方协商出一个对称密钥。
- 数字签名:用私钥签名,公钥验签。这个后面细说。
3.3 哈希函数:固件的「指纹」
哈希函数,就是把任意长度的数据,压缩成固定长度的摘要。这个摘要有几个特点:
- 不可逆:从摘要反推原始数据,几乎不可能。
- 抗碰撞:很难找到两个不同的数据,哈希值相同。
- 雪崩效应:输入改一个 bit,输出完全变样。
常用的哈希算法:
| 算法 | 摘要长度 | 安全性 |
|---|---|---|
| MD5 | 128 bit | 已破解,别用 |
| SHA-1 | 160 bit | 已破解,别用 |
| SHA-256 | 256 bit | 安全,推荐 |
| SM3 | 256 bit | 国标,安全 |
哈希函数在固件安全里,最常见的用法是完整性校验。固件烧录前,计算哈希值;烧录后,再算一次。两个值一样,说明固件没被篡改。我在项目中遇到过,有人用 MD5 做固件校验,结果攻击者伪造了一个固件包,MD5 碰撞成功,直接绕过了校验。从那以后,我所有项目都强制用 SHA-256。
3.4 数字签名:给固件盖上「官方印章」
数字签名,就是非对称加密 + 哈希函数的组合拳。流程是这样的:
- 发布方对固件计算哈希值。
- 用私钥对哈希值加密,生成签名。
- 把固件和签名一起发布。
- 接收方用公钥解密签名,得到哈希值。
- 接收方自己计算固件的哈希值。
- 两个哈希值对比,一致则签名验证通过。
你想想看,只要私钥不泄露,攻击者就无法伪造签名。这就解决了固件的真实性和完整性两个问题。
常见的签名算法:
- RSA-PSS:RSA 的概率签名方案,比传统 PKCS#1 v1.5 更安全。
- ECDSA:基于 ECC 的签名算法,效率高。
- SM2 签名:国标签名算法。
- Ed25519:现代签名算法,速度快,安全性高。我最近几个项目都在用这个。
3.5 知识体系总览
下面这张图,把本章的核心逻辑串起来了。你一看就明白,这四块技术是怎么配合的。
3.6 实际项目中的组合策略
光讲理论不行,咱们看看实际项目里怎么搭。我总结了一个通用方案,你拿去就能用:
| 步骤 | 做什么 | 用什么技术 |
|---|---|---|
| 1 | 生成对称密钥 | 真随机数发生器(TRNG) |
| 2 | 用公钥加密对称密钥 | RSA-2048 或 ECC P-256 |
| 3 | 用对称密钥加密固件 | AES-128-GCM |
| 4 | 计算固件哈希 | SHA-256 |
| 5 | 对哈希值签名 | ECDSA 或 Ed25519 |
| 6 | 打包:加密固件 + 加密密钥 + 签名 | 自定义格式或标准容器 |
设备端启动时,先验签,再解密。验签失败,直接死循环。没有商量余地。