OTA 加密完整方案(嵌入式 IoT 常用)

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 加密大固件速度快、开销低)

完整流程(服务器端打包)
  1. 生成一次性CEK(内容密钥,AES-128/256) ,随机生成,每个固件包用独立 CEK
  2. 使用 CEK + IV,用 AES-GCM 加密整个固件 bin,得到密文固件 + auth tag(校验标签)
  3. 用设备公钥(RSA/ECDH)加密这个 CEK,把【加密后的 CEK + IV + tag + 密文固件】打包成 OTA 包
  4. 再对整个固件元数据 / 固件哈希做数字签名(私钥签名),附加到包头部 /manifest 清单
设备端流程(Bootloader/APP 里执行)
  1. 下载完整 OTA 包,先验签 :用设备内置的公钥校验签名,签名失败直接丢弃,不做解密(防止耗算力的拒绝服务攻击)
  2. 验签通过后,取出加密的 CEK,用设备私钥解密得到 CEK
  3. 使用 CEK、IV,AES-GCM 解密密文固件,同时校验 auth tag;tag 错误 = 固件被篡改,拒绝升级
  4. 解密得到明文固件,写入运行分区;双分区 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 镜像加密是两套东西。

四、开发落地要点

  1. 验签一定要在解密前面,不要先解密再验签,会存在拒绝服务、密码学攻击风险。
  2. AES-GCM 的 IV 必须随机、唯一,同一个 CEK 不能重复 IV;IV 明文随 OTA 包下发,不需要保密。
  3. A/B 双分区:新固件下载到备用分区,解密 + 验签全部通过后,才切换启动分区;启动失败自动回滚到老版本。
  4. 防回滚:存入安全存储的版本号计数器,不允许刷低于当前版本的固件,防止降级攻击。
  5. 密码库: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。

六、常见坑

  1. 只做 SHA256 哈希校验,没有数字签名:攻击者可以替换固件,同时修改哈希值,完全绕过。
  2. 把签名和加密顺序搞反,先解密再验签。
  3. AES 复用 IV,直接破坏 AES-GCM 安全。
  4. 密钥明文放在固件 bin 里,一 dump 全部泄露。
  5. 没有 A/B 分区,升级中途断电直接变砖。
相关推荐
apcipot_rain6 小时前
C++转Java日记(05)
java·开发语言·c++
apcipot_rain15 小时前
C++转Java日记(04)
java·开发语言·c++
wuyk55515 小时前
Keil工具链-第05讲-启动文件与__main到底做了什么
c语言·stm32·单片机·嵌入式硬件·物联网
云和数据.ChenGuang16 小时前
LangGraph 异步 Node 的设计与写法实践
开发语言·人工智能·python·机器学习·php
蜗牛一步步往上爬19 小时前
第十六章 C++语言在深度学习中的应用
开发语言·c++·深度学习
张张123y21 小时前
DSH 插件调试避坑:client.js 设置面板、热重载与高频报错排查表
开发语言·javascript·人工智能·开源·ecmascript·后端开发·ai agent
冻柠檬飞冰走茶1 天前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
FRing031 天前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
雪落漂泊1 天前
C++算法 二分查找篇(上)
开发语言·c++·算法
波力海苔夹心脆6751 天前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典