《物联网设备安全基线设定》
第4章 固件安全

4、固件安全:固件加密、签名验证、安全启动链(Secure Boot)

固件是物联网设备的“灵魂”,其安全性直接决定了设备是否会被恶意控制、篡改或用于发起网络攻击。本节将深入探讨固件安全的三大核心支柱:固件加密、签名验证与安全启动链(Secure Boot),帮助您建立从存储到运行的全链路防护基线。

🔒 固件加密 防止逆向与静态分析 保护敏感数据与密钥 ✍️ 签名验证 确保固件来源可信 防止篡改与伪造 🛡️ 安全启动链 逐级信任度量 阻止恶意代码执行 三者协同构建“存储→传输→执行”全生命周期安全防线

4.1 固件加密

固件加密旨在保护固件在静态存储(如Flash、外部存储芯片)和传输过程(如OTA升级)中的机密性。即使攻击者通过物理手段读取了存储芯片,也无法直接获取固件的原始代码与敏感数据。

加密层级 典型算法 密钥管理要求
固件镜像加密 AES-256-GCM 密钥存储在安全元件(SE)或TEE中
分区加密 XTS-AES-128/256 每个设备唯一密钥,硬件绑定
OTA传输加密 TLS 1.3 + 固件层加密 证书链验证 + 临时会话密钥
原始固件 AES-256 加密引擎 加密固件 安全存储(Flash) 运行时解密(RAM) 硬件密钥解密

4.2 签名验证

签名验证是固件完整性与真实性的核心保障。设备在加载固件前,必须使用预置的公钥验证数字签名,确保固件来自受信任的厂商且未被篡改。

  • 签名算法基线:推荐使用 ECDSA(P-256/P-384)或 Ed25519,避免使用 RSA-1024 及以下弱密钥。
  • 签名流程:厂商使用私钥对固件哈希值签名 → 设备使用公钥验签 → 匹配则加载,否则拒绝启动。
  • 密钥保护:签名私钥必须存储在硬件安全模块(HSM)中,公钥烧录在设备一次性可编程(OTP)区域。
  • 防回滚:签名结构中应包含版本号字段,设备拒绝加载低于当前版本的固件。
厂商签名 私钥签名(HSM) 生成签名文件.sig 固件包 固件镜像 + 签名 版本号 + 哈希值 设备验签 OTP公钥验证 通过→加载 失败→拒绝 🔑 公钥基础设施(PKI)是签名验证的信任基石

4.3 安全启动链(Secure Boot)

安全启动链是一种逐级信任度量机制,从芯片ROM代码开始,每一级在加载下一级之前,都必须验证其签名与完整性。任何一级验证失败,系统立即停止启动,防止恶意代码注入。

🔗 典型安全启动链层级

  1. ROM Bootloader(不可变):芯片出厂固化的第一段代码,验证下一级Bootloader的签名。
  2. SPL / 二级Bootloader:验证U-Boot或类似引导程序的完整性与签名。
  3. U-Boot / 引导程序:验证操作系统内核(如Linux Kernel)的签名。
  4. 操作系统内核:验证关键内核模块与设备驱动签名。
  5. 系统服务与应用:验证用户空间关键服务的完整性(可选扩展)。
🔒 第1级:ROM Bootloader(硬件不可变,信任根) ✅ 第2级:SPL / 二级Bootloader(验证签名) ✅ 第3级:U-Boot / 引导程序(验证内核签名) ✅ 第4级:操作系统内核(验证模块签名) ✅ 第5级:系统服务与应用 信任链传递方向

4.4 基线要求与最佳实践

安全域 基线要求 强制/建议
固件加密 使用AES-256-GCM加密固件镜像,密钥与硬件绑定 强制
签名算法 ECDSA P-256 或 Ed25519,禁止使用MD5/SHA-1 强制
安全启动 实现从ROM到内核的完整签名验证链 强制
防回滚 签名结构中包含版本号,拒绝降级攻击 强制
密钥存储 私钥存储在HSM,公钥存储在OTP/eFuse 强制

4.5 代码示例:固件签名与验证(伪代码)

// 厂商侧:固件签名
private_key = load_private_key_from_hsm("device_signing_key.pem")
firmware_hash = sha256("firmware_v2.1.bin")
signature = ecdsa_sign(private_key, firmware_hash)
firmware_package = package(firmware_binary, signature, version="2.1")
save_to_file(firmware_package, "firmware_v2.1_signed.bin")

// 设备侧:安全启动验签
if (boot_stage == ROM) {
    public_key = read_otp_public_key()
    next_stage = load_next_bootloader()
    is_valid = ecdsa_verify(public_key, next_stage.hash, next_stage.signature)
    if (!is_valid || next_stage.version < current_version) {
        halt_boot("Security violation: Invalid signature or rollback detected!")
    }
    jump_to(next_stage)
}

⚠️ 关键提醒:安全启动链的强度取决于最薄弱的环节。务必确保信任根(ROM代码)不可篡改,且公钥烧录过程在安全环境下进行。定期审计固件签名策略,及时撤销泄露的证书。

专注课程资料整理