OTA 安全分传输加密 、固件包本身加密(存储加密) 、**固件数字签名(验签,防篡改 / 伪造)**三块,很多人容易混淆:签名保证包是官方、没被改;加密保证别人截获后看不懂固件内容,两者必须搭配,不能只用一个。
推荐算法:
- 固件内容加密:AES-GCM(AEAD,加密 + 完整性一体,首选),其次 AES-CCM;不要单独 AES-CBC/CTR(还要额外做 MAC,容易踩坑)
- 签名验签:ECDSA P256(资源小,MCU 首选);大容量设备可用 RSA2048/RSA3072
- 传输:HTTPS (TLS1.2/1.3)、MQTTs、CoAPs
一、两种加密维度
1)传输链路加密(网络传输时加密)
作用:固件在服务器→设备网络链路上,中间人抓包只能拿到密文。
- 实现:直接用 TLS。HTTP→HTTPS,MQTT→MQTTs,CoAP→CoAPs
- 优点:最简单,不需要改固件包格式,设备端只需要 mbedtls/tinycrypt
- 局限:下载到设备本地 flash 的固件仍是明文;攻击者拿到 flash 可以直接 dump 固件逆向。
适合:只防网络抓包,不需要保护固件镜像本身。
2)固件镜像加密(包本身加密,重点)
目标:下载到设备 flash 里的 OTA 镜像也是密文,即使读出 flash 也看不到明文固件。
架构:非对称密钥分发 + 对称 AES 加密固件(标准做法,因为 AES 加密大固件速度快、开销低)
完整流程(服务器端打包)
- 生成一次性CEK(内容密钥,AES-128/256) ,随机生成,每个固件包用独立 CEK
- 使用 CEK + IV,用 AES-GCM 加密整个固件 bin,得到密文固件 + auth tag(校验标签)
- 用设备公钥(RSA/ECDH)加密这个 CEK,把【加密后的 CEK + IV + tag + 密文固件】打包成 OTA 包
- 再对整个固件元数据 / 固件哈希做数字签名(私钥签名),附加到包头部 /manifest 清单
设备端流程(Bootloader/APP 里执行)
- 下载完整 OTA 包,先验签 :用设备内置的公钥校验签名,签名失败直接丢弃,不做解密(防止耗算力的拒绝服务攻击)
- 验签通过后,取出加密的 CEK,用设备私钥解密得到 CEK
- 使用 CEK、IV,AES-GCM 解密密文固件,同时校验 auth tag;tag 错误 = 固件被篡改,拒绝升级
- 解密得到明文固件,写入运行分区;双分区 A/B 分区,启动校验失败可回滚
密钥存储重点:
- 设备私钥 不能直接放在普通 flash,优先放安全芯片 SE/TEE/MCU eFuse;
- 验签用的公钥可以烧录在固件 /efuse,公开不怕泄露;
- 服务器签名私钥离线保管,HSM 硬件密码机保存,绝对不能放到 web 服务器。
二、极简选型对比
表格
| 方案 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 仅 TLS 传输加密 | HTTPS/MQTTs | 实现最简单,不用改 bin 包 | flash 里固件明文,可 dump 逆向 | 简单小设备,不担心固件被 dump |
| AES 对称预共享密钥 (PSK) | 设备和服务器烧同一个 AES 密钥加密固件 | 运算快,代码量小 | 密钥泄露所有设备全部沦陷,密钥更新麻烦 | 封闭小批量项目,不推荐量产 |
| AES-GCM + ECDH/RSA 密钥封装(推荐) | AES 加密固件,非对称传递 AES 密钥 | 每个包 CEK 独立;密钥泄露影响范围小;AEAD 自带完整性 | 代码复杂,需要非对称密码库 | 量产 IoT,工业、车载 OTA |
三、和 Secure Boot(安全启动)的关系
Secure Boot:Bootloader 只允许验签通过的固件运行,不负责加密;就算固件是明文,没有合法签名就拒绝启动。
- 组合最佳实践:镜像 AES 加密 + Secure Boot 验签 + A/B 双分区 + 版本防回滚(anti-rollback,版本计数器)
- ESP32 等芯片还有硬件 Flash 加密:固件写入 flash 时硬件自动加密,属于片内存储加密,和 OTA 镜像加密是两套东西。
四、开发落地要点
- 验签一定要在解密前面,不要先解密再验签,会存在拒绝服务、密码学攻击风险。
- AES-GCM 的 IV 必须随机、唯一,同一个 CEK 不能重复 IV;IV 明文随 OTA 包下发,不需要保密。
- A/B 双分区:新固件下载到备用分区,解密 + 验签全部通过后,才切换启动分区;启动失败自动回滚到老版本。
- 防回滚:存入安全存储的版本号计数器,不允许刷低于当前版本的固件,防止降级攻击。
- 密码库:mbedtls、tinycrypt、wolfssl;优先开启 MCU 硬件加密加速器(AES、SHA、ECC),降低 CPU 开销。
五、最简 OpenSSL 演示(服务器打包示意)
# 1.生成AES256-GCM的CEK和IV
CEK=$(openssl rand -hex 32)
IV=$(openssl rand -hex 12)
# 2.AES-GCM加密固件bin,输出密文+tag
openssl enc -aes-256-gcm -K $CEK -iv $IV -in app.bin -out app_enc.bin -tag app.tag
# 3.用RSA公钥加密CEK,把加密后的CEK、IV、tag、密文打包进OTA头部
# 4.用RSA/ECDSA私钥对固件哈希签名,附加到包头部
设备端逆操作:验签 → RSA 解密取出 CEK → AES-GCM 解密并校验 tag。
六、常见坑
- 只做 SHA256 哈希校验,没有数字签名:攻击者可以替换固件,同时修改哈希值,完全绕过。
- 把签名和加密顺序搞反,先解密再验签。
- AES 复用 IV,直接破坏 AES-GCM 安全。
- 密钥明文放在固件 bin 里,一 dump 全部泄露。
- 没有 A/B 分区,升级中途断电直接变砖。