2、密码学基础:哈希算法、非对称加密与数字签名在Secure Boot中的角色

Secure Boot 的信任链本质上是一条“测量—签名—验证”的密码学链路。要理解这条链路,必须先掌握三个核心构件:哈希算法(如 SHA-256)、非对称加密(RSA/ECC)以及数字签名。哈希负责为固件生成“指纹”,非对称加密负责提供一对公私钥来完成签名与验签,而数字签名则将两者结合,确保固件的完整性与来源真实性。本章将逐一拆解这些基础概念,并说明它们在 Secure Boot 启动流程中的具体落位。

哈希算法层 非对称加密层 数字签名层 固件镜像 Bootloader.bin SHA-256 计算 输出 256-bit 摘要 摘要 H(M) 64位十六进制字符串 特性 • 单向性:不可逆 • 抗碰撞:不同输入不同摘要 密钥对生成 RSA-2048 / ECC P-256 私钥 签名用·保密 公钥 验签用·公开 数学基础 大整数分解 / 椭圆曲线离散对数 工程约束 • 私钥存于HSM或OTP • 公钥哈希烧录于eFuse 签名生成 私钥加密摘要 → 签名值 签名验证 公钥解密签名 → 得到摘要 摘要比对 H(M) == 解密结果 ? 安全属性 • 完整性:防篡改 • 真实性:防伪造 输入 输入

2.1 哈希算法:固件完整性的“指纹”

核心原理

哈希算法(Hash Algorithm)是一种将任意长度输入数据映射为固定长度输出的数学函数。在 Secure Boot 场景中,SHA-256 是最常用的哈希算法,其输出固定为 256 位(32 字节),通常以 64 位十六进制字符串表示。哈希函数具备三个关键特性:单向性(由摘要无法反推原文)、抗碰撞性(极难找到两个不同输入产生相同摘要)、雪崩效应(输入微变,输出剧变)。这些特性使得哈希值可以作为固件镜像的“数字指纹”。

工程要点:SHA-256 在 Secure Boot 中承担“测量”职责。BootROM 读取 Flash 中的 Bootloader 镜像,逐块计算 SHA-256 摘要,然后将该摘要与预先存储的“黄金摘要”比对。任何一位比特的翻转都会导致摘要完全不同,从而被立即发现。

判断方法与操作流程

在实际开发中,验证哈希计算是否正确,通常采用以下流程:

  1. 使用工具(如 sha256sum、OpenSSL)计算固件文件的 SHA-256 值。
  2. 在目标板上通过串口打印 BootROM 计算出的摘要值。
  3. 对比两者是否一致。若不一致,检查镜像加载地址、填充字节或签名附加方式。
# 主机端计算固件哈希
$ sha256sum bootloader.bin
3b3a5c2f8e9d1a4b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b  bootloader.bin

# 目标板串口输出(示例)
BootROM: SHA-256 digest = 3b3a5c2f8e9d1a4b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b
Verification: PASS

案例拆解:一次固件损坏的定位

某 IoT 设备在 OTA 升级后频繁启动失败。工程师通过串口日志发现 BootROM 报出 HASH_MISMATCH 错误。初步怀疑是 Flash 写入异常。进一步分析发现,OTA 升级包在传输过程中被网关截断,导致固件尾部 4KB 数据丢失。由于 SHA-256 对输入数据的每一位都敏感,即使只缺失 1 字节,摘要也会完全不同。最终通过重新下载完整升级包并校验哈希值解决了问题。此案例说明,哈希校验是 Secure Boot 第一道防线,能有效拦截不完整或损坏的固件。

常见误区与总结

  • 误区一:认为 MD5 或 SHA-1 仍可用于 Secure Boot。实际上,SHA-1 已被证明存在碰撞攻击,主流芯片厂商已全面转向 SHA-256 或更高强度算法。
  • 误区二:忽略哈希计算的输入范围。签名时通常只对固件镜像本身计算哈希,而不包含签名块或头部元数据,否则会导致验证失败。
  • 误区三:将哈希值直接存储在可写 Flash 中。正确做法是存储在一次性可编程(OTP)区域或 eFuse 中,防止被篡改。

2.2 非对称加密:RSA 与 ECC 的工程选型

核心原理

非对称加密使用一对数学关联但不可互推的密钥:公钥(Public Key)和私钥(Private Key)。用私钥加密的数据只能用公钥解密,反之亦然。在 Secure Boot 中,私钥由固件开发者或设备制造商严密保管,用于对固件签名;公钥则嵌入设备中,用于验证签名。目前主流算法为 RSA(基于大整数分解难题)和 ECC(基于椭圆曲线离散对数难题)。

对比维度 RSA-2048 ECC P-256
密钥长度 2048 位 256 位
签名长度 256 字节 64 字节
计算开销 较高(大数模幂) 较低(椭圆曲线点乘)
安全强度 约 112 位对称等价 约 128 位对称等价
典型应用 PC/服务器、传统 MCU 车规芯片、低功耗 IoT
选型建议:对于资源受限的嵌入式设备(如 Cortex-M0+),ECC 因签名短、计算快而更受青睐;对于性能较强的应用处理器(如 Cortex-A 系列),RSA 的软件生态更成熟。部分芯片同时支持两种算法,可在安全启动配置中灵活选择。

密钥管理与存储

私钥的安全是整个信任链的根基。生产环境中,私钥应存储在硬件安全模块(HSM)中,并通过密钥管理策略限制访问权限。设备端的公钥通常以“公钥哈希”的形式烧录到 eFuse 中,BootROM 启动时先读取 eFuse 中的哈希值,再对 Flash 中存储的公钥进行哈希比对,防止公钥被替换。

# 生成 RSA-2048 密钥对(示例)
$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem
$ openssl rsa -in private.pem -pubout -out public.pem

# 生成 ECC P-256 密钥对
$ openssl ecparam -name prime256v1 -genkey -noout -out ec_private.pem
$ openssl ec -in ec_private.pem -pubout -out ec_public.pem

案例拆解:密钥泄露后的应急响应

某厂商在开发阶段误将签名私钥提交到公开代码仓库。安全团队发现后立即启动应急流程:首先,确认泄露时间窗口内发布的固件版本;其次,生成新的密钥对,并通过安全 OTA 机制更新所有已部署设备的公钥;最后,对旧密钥签名的固件设置“过期时间”,强制设备在下次启动时拒绝旧签名。整个过程耗时 72 小时,期间停产 1 天。此案例警示:私钥必须与开发环境隔离,建议使用独立签名服务器或 HSM 进行签名操作。

常见误区与总结

  • 误区一:认为公钥可以随意存储。实际上,公钥本身也需要完整性保护,否则攻击者可以替换公钥并伪造签名。
  • 误区二:忽略密钥长度与安全等级的匹配。例如,使用 1024 位 RSA 在 2025 年的安全环境中已不推荐。
  • 误区三:将私钥用于加密而非签名。Secure Boot 中私钥只用于签名,不用于数据加密,避免扩大泄露面。

2.3 数字签名:完整性与真实性的双重保障

核心原理

数字签名是将哈希算法与非对称加密结合的产物。签名过程为:发送方对固件镜像计算 SHA-256 摘要,然后用私钥对摘要进行加密,生成签名值。验证过程为:接收方用公钥解密签名值得到摘要 A,同时对收到的固件重新计算摘要 B,若 A 与 B 相等,则证明固件未被篡改且确实来自持有私钥的一方。这一机制同时提供了完整性(防篡改)和真实性(防伪造)保证。

关键区别:数字签名不是“加密整个固件”,而是“加密固件的哈希值”。这样做既节省了计算资源,又避免了大块数据的加解密开销。Secure Boot 中签名验证通常只涉及 32 字节摘要的加解密,耗时极短。

操作流程:Secure Boot 中的签名验证链路

  1. BootROM 阶段:读取 eFuse 中的根公钥哈希,验证 Flash 中存储的根公钥。
  2. 签名验证:用根公钥验证 Bootloader 的数字签名,同时计算 Bootloader 的 SHA-256 摘要。
  3. 信任传递:Bootloader 验证通过后,加载并验证 OS Kernel 的签名,形成链式信任。
  4. 失败处理:任何一级验证失败,立即停止启动并进入恢复模式。
// 伪代码:签名验证流程
digest = SHA256(firmware_image);
decrypted_digest = RSA_Decrypt(signature, public_key);
if (digest == decrypted_digest) {
    boot_continue();
} else {
    enter_recovery_mode();
}

案例拆解:签名绕过攻击的防御

某安全研究团队尝试通过修改 Bootloader 中的公钥存储位置来绕过签名验证。他们发现设备将公钥存放在外部 SPI Flash 中,且未做写保护。攻击者替换公钥后,用自己的私钥对恶意固件签名,成功启动。修复方案是:将公钥的 SHA-256 哈希烧录到 eFuse 中,BootROM 每次启动时先校验公钥哈希,再执行签名验证。这一改动彻底封堵了公钥替换攻击路径。此案例说明,签名验证的强度不仅取决于算法,还取决于公钥存储的可信性。

常见误区与总结

  • 误区一:认为签名验证只需做一次。实际上,Secure Boot 是多级验证,每一级引导程序都要验证下一级的签名。
  • 误区二:忽略签名算法的填充方式。RSA 签名通常使用 PKCS#1 v1.5 或 PSS 填充,验证时必须匹配。
  • 误区三:将签名值附加在固件末尾后,未调整哈希计算范围。正确做法是:哈希只覆盖固件主体,签名值单独存放。

2.4 三者在 Secure Boot 中的协同工作

信任链的建立

Secure Boot 的信任链从芯片内部的 BootROM 开始。BootROM 是芯片出厂时固化的代码,不可篡改。它首先使用 eFuse 中存储的根公钥哈希来验证外部 Flash 中的根公钥,然后使用该公钥验证 Bootloader 的签名。Bootloader 验证通过后,再加载并验证 OS Kernel。每一级验证都包含哈希计算和签名验证两个步骤,形成“测量—验证—传递”的闭环。

启动阶段 验证对象 使用的密码学操作 失败后果
BootROM 根公钥 SHA-256 比对 无法启动
Bootloader 固件签名 RSA/ECC 验签 + SHA-256 进入恢复模式
OS Kernel 内核镜像签名 RSA/ECC 验签 + SHA-256 拒绝加载

性能优化与安全平衡

在实际产品中,签名验证会增加启动时间。以 RSA-2048 为例,一次验签在 1GHz 处理器上约耗时 1-2ms,在 100MHz MCU 上可能达到 20-50ms。为优化性能,可采取以下措施:

  • 使用硬件加速器(如 CryptoCell、CAAM)执行 RSA/ECC 运算。
  • 采用 ECC 算法减少签名长度和计算量。
  • 对启动镜像进行分块哈希,先验证关键头部,再验证主体。
设计建议:在系统启动时间预算中预留 50-100ms 用于安全验证。若超出预算,优先考虑硬件加速而非降低安全等级。同时,建议在开发阶段就启用 Secure Boot 验证,避免产品量产后再补加导致兼容性问题。

案例拆解:车规级 MCU 的 Secure Boot 实现

某车规级 MCU 项目要求启动时间小于 200ms,且必须满足 ISO 21434 网络安全标准。工程师选择了 ECC P-256 算法,并利用芯片内置的硬件加密引擎。实测结果:BootROM 验签耗时 3.2ms,Bootloader 验签耗时 4.1ms,总安全验证开销 7.3ms,远低于预算。同时,他们将公钥哈希存储在 16 字节 eFuse 中,并启用了 eFuse 的写保护。该设计通过了功能安全与网络安全双重评审。此案例表明,合理的算法选型与硬件加速结合,可以在严苛约束下实现高安全启动。

常见误区与总结

  • 误区一:认为 Secure Boot 只是“加个签名”而已。实际上,它涉及密钥管理、硬件信任根、启动流程改造等多个维度。
  • 误区二:忽略安全启动失败后的恢复机制。产品必须提供安全的恢复路径(如 USB 烧录、安全 OTA),否则设备可能变砖。
  • 误区三:将安全启动与加密启动混淆。Secure Boot 只验证签名,不加密固件内容;加密启动(Encrypted Boot)则额外对固件进行解密,两者可组合使用。

综上所述,哈希算法、非对称加密与数字签名构成了 Secure Boot 的密码学基石。理解它们的原理、工程实现与常见陷阱,是设计可信启动链路的必要前提。在实际项目中,应根据芯片能力、启动时间预算和安全等级要求,综合选择算法与密钥管理策略,确保从第一行代码到操作系统内核的每一级加载都经过严格验证。