4. 安全启动原理

ESP32 的安全启动(Secure Boot)本质上是一套“信任链”机制:芯片复位后,从一段不可修改的 ROM 代码开始,逐级校验下一阶段固件的完整性与真实性,只有校验通过才允许执行。这样即使攻击者能物理接触 Flash 并改写内容,也无法让设备运行未授权固件。理解安全启动,关键要抓住四个问题:信任根在哪里、引导流程如何逐级传递、签名与摘要如何验证、v1 与 v2 有何差异。

一、信任链:从 ROM 到应用的逐级传递

信任链(Chain of Trust)的起点是芯片内部固化的 BootROM。BootROM 在芯片出厂时写入,用户无法修改,因此它天然可信,被称为“信任根”。BootROM 首先读取 eFuse 中的安全启动配置位,判断是否启用安全启动、使用哪一版本、以及公钥摘要是否已烧录。随后它加载 Flash 中的引导程序(bootloader),用 eFuse 中保存的公钥摘要去校验 bootloader 的签名。校验通过后,控制权交给 bootloader;bootloader 再用同样的方式校验分区表与应用程序镜像。如此一级信任一级,形成完整链条。

信任链的核心思想是:每一级在执行下一级之前,必须先验证下一级的签名。任何一级校验失败,芯片就会停止启动或进入复位循环,绝不会“带病运行”。

ESP32 安全启动信任链与引导流程 BootROM 信任根 · 不可修改 eFuse 安全配置 公钥摘要 · 版本位 · 使能位 Bootloader 镜像 含签名块 · 被 ROM 校验 读取 校验 分区表 被 Bootloader 校验 应用程序镜像 被 Bootloader 校验 校验 校验 签名验证与摘要校验 镜像数据 计算 SHA-256 摘要值 与签名块比对 RSA 公钥 验签 公钥摘要烧录于 eFuse,防止公钥被替换 摘要一致 → 镜像未被篡改 签名有效 → 镜像来源可信 任一环节校验失败 → 启动中止 / 复位循环,不执行未授权固件

二、引导流程:从上电到应用执行

以 ESP32 为例,启用安全启动后的典型引导流程如下:

  1. 上电复位:CPU 从 BootROM 开始执行。
  2. 读取 eFuse:确认 ABS_DONE_0(v1)或 SECURE_BOOT_EN(v2)等使能位,以及公钥摘要。
  3. 校验 bootloader:BootROM 计算 bootloader 镜像摘要,并用 eFuse 中的公钥摘要验证其签名块。
  4. 执行 bootloader:校验通过后跳转执行,bootloader 初始化 Flash、时钟等。
  5. 校验分区表与应用:bootloader 依次校验分区表和目标应用镜像的签名。
  6. 跳转应用:全部通过后,将控制权交给应用程序。

整个过程是“先验证、后执行”,且验证逻辑位于上一级可信代码中,攻击者无法跳过。

三、签名验证与摘要校验:两件事,缺一不可

安全启动同时解决两个问题:完整性(内容有没有被改)和真实性(是不是授权方发布的)。

  • 摘要校验:对镜像数据计算 SHA-256 摘要,与镜像中签名块内保存的摘要比对。若镜像被篡改,摘要必然不同,校验失败。摘要保证完整性。
  • 签名验证:签名块中的摘要由私钥签名,芯片用 eFuse 中保存的公钥摘要对应的公钥验签。只有持有私钥的授权方才能生成有效签名。签名保证真实性。

公钥本身不直接烧录,而是烧录其摘要。这样即使 eFuse 内容被读取,也无法反推出完整公钥,更无法伪造私钥签名。签名算法通常为 RSA-3072(v2)或 RSA-2048(v1),摘要算法为 SHA-256。

关键点:摘要校验防篡改,签名验证防伪造。两者结合,才能确保“内容正确且来源可信”。

四、安全启动 v1 与 v2 的差异

ESP32 支持安全启动 v1 和 v2 两个版本,二者在密钥长度、配置方式和安全性上有明显区别。下表为对比清单:

对比项 安全启动 v1 安全启动 v2
签名算法 RSA-2048 RSA-3072
摘要算法 SHA-256 SHA-256
eFuse 使能位 ABS_DONE_0 SECURE_BOOT_EN
密钥撤销 不支持 支持密钥撤销与多密钥
安全强度 较低,已不推荐新设计 更高,推荐使用
适用场景 早期产品、兼容旧方案 新量产项目、高安全需求

v2 不仅密钥更长,还引入了密钥撤销机制:当某把私钥泄露时,可通过烧录撤销位使对应公钥失效,从而在不更换芯片的前提下阻断旧密钥签名的固件。v1 缺乏这一能力,一旦私钥泄露,只能更换芯片或接受风险。

五、常见误区与复盘

误区一:以为烧录了签名固件就安全了。安全启动必须先在 eFuse 中烧录公钥摘要并使能安全启动,否则芯片仍会执行未签名固件。仅签名不使能,等于没有防护。

误区二:忽略 eFuse 的不可逆性。安全启动使能位和公钥摘要一旦烧录通常不可撤销。量产前务必在测试芯片上完整验证,避免整批芯片被锁死。

复盘建议:启用安全启动前,先用 espefuse.py summary 确认 eFuse 状态;用 espsecure.py sign_data 对镜像签名;用 esptool.py 烧录后观察串口日志中的校验结果。若启动失败,优先检查公钥摘要是否与签名私钥匹配、镜像是否被重新打包覆盖了签名块。

# 查看 eFuse 状态
espefuse.py --port /dev/ttyUSB0 summary

# 对 bootloader 签名(示例)
espsecure.py sign_data --keyfile private_key.pem \
  --version 2 bootloader.bin

# 烧录后串口日志关键行
I (31) boot: Secure Boot enabled
I (35) boot: Verifying signature of bootloader...
I (52) boot: Signature verified successfully

掌握信任链、引导流程、签名与摘要的分工,以及 v1/v2 的差异,是正确配置和排查 ESP32 安全启动的基础。实际项目中应优先选择 v2,并在量产前完成完整的签名、烧录与启动验证闭环。