3、密码学基础:哈希、数字签名、非对称加密、证书体系在安全启动中的应用
安全启动(Secure Boot)的信任链本质上是密码学原语的工程化编排。从硬件复位到操作系统内核加载,每一个环节的完整性校验、来源认证和防回滚机制,都依赖于哈希函数、非对称加密、数字签名和证书体系这四大支柱。理解这些密码学组件如何协同工作,是构建可信启动链的前提。本章将逐一剖析这些基础概念,并重点说明它们在UEFI安全启动、ARM TrustZone和嵌入式Linux启动流程中的具体落点。
3.1 哈希函数:完整性度量的基石
核心原理
哈希函数(如SHA-256、SHA-384)将任意长度的二进制数据映射为固定长度的摘要值。在安全启动中,哈希并非用于加密,而是作为完整性度量的工具。其核心特性包括:单向性(无法从摘要反推原文)、抗碰撞性(难以找到两个不同输入产生相同输出)、雪崩效应(输入微变,输出剧变)。BootROM在加载下一级镜像前,先计算镜像的哈希值,并与存储在eFuse或OTP中的黄金哈希比对,任何比特位的篡改都会导致校验失败。
判断方法与操作流程
在实际工程中,哈希校验通常遵循以下流程:
- 镜像生成:编译完成后,对二进制镜像计算SHA-256哈希,生成
image.sha256文件。 - 哈希存储:将哈希值烧录到芯片的eFuse区域(一次性可编程),或存储在受保护的Flash分区。
- 启动校验:BootROM读取镜像,硬件加速器计算哈希,与eFuse中的值进行常量时间比较。
- 失败处理:若不一致,进入恢复模式或拒绝启动,并记录安全事件。
工程要点:哈希校验只能证明镜像未被修改,但无法证明镜像来自可信来源。攻击者可以替换镜像并同步更新哈希值(如果哈希存储区可写)。因此,哈希必须与数字签名配合使用,或者将哈希存储在硬件不可变区域。
案例拆解:eFuse哈希校验失败排查
某嵌入式设备在量产阶段出现偶发性启动失败,日志显示HASH MISMATCH at stage 2。初步排查发现,BootROM计算的哈希与eFuse中的参考值不一致。进一步分析发现,问题并非镜像被篡改,而是eFuse编程时序异常导致部分比特位翻转。由于eFuse是一次性可编程,该批次芯片无法修复,只能报废。复盘结论:在eFuse烧录后必须增加回读校验步骤,并在产线测试中增加哈希校验的覆盖率。
常见误区
- 误区一:认为哈希可以替代签名。哈希只提供完整性,不提供认证性。
- 误区二:使用MD5或SHA-1。这些算法已被证明存在碰撞攻击,安全启动中应使用SHA-256及以上。
- 误区三:忽略哈希比较的时间侧信道。应使用恒定时间比较函数,防止时序攻击。
3.2 非对称加密与数字签名:认证与防篡改
核心原理
非对称加密使用一对密钥:私钥(保密存储)和公钥(公开分发)。在安全启动中,主要应用是数字签名:签名者使用私钥对镜像的哈希值进行加密运算,验证者使用公钥解密并比对哈希。RSA-2048和ECC P-256是当前主流选择。ECC在相同安全强度下密钥更短、运算更快,适合资源受限的嵌入式环境。
签名与验证流程
| 步骤 | 签名方(开发/构建服务器) | 验证方(目标设备) |
|---|---|---|
| 1 | 计算镜像哈希 H = SHA-256(Image) | 计算镜像哈希 H' = SHA-256(Received Image) |
| 2 | 使用私钥加密 H,生成签名 Sig | 使用公钥解密 Sig,得到 H'' |
| 3 | 将 Image || Sig 打包发布 | 比较 H' 与 H'',一致则通过 |
经验提醒:在ARM平台,签名算法通常采用PKCS#7或CMS格式封装,将签名、证书链和镜像元数据打包在一起。U-Boot的CONFIG_FIT_SIGNATURE功能即采用此方案,支持多镜像联合签名。
案例拆解:U-Boot FIT镜像签名实施
某网关产品需要支持安全启动,选择U-Boot作为引导加载程序。实施步骤如下:
- 生成密钥对:使用OpenSSL生成RSA-2048私钥,私钥存储在HSM中,公钥嵌入U-Boot设备树。
- 创建FIT镜像:将内核、设备树、initramfs打包为
.its源文件,编译生成.itb镜像。 - 签名配置:在U-Boot配置中启用
CONFIG_FIT_SIGNATURE=y,并指定公钥的存放位置。 - 验证测试:正常启动通过;人为修改内核镜像后,U-Boot报错
Bad hash value for 'kernel' node,启动终止。
该方案的关键约束是公钥的完整性。如果攻击者替换了设备树中的公钥,签名验证将失去意义。因此,公钥本身必须由上一级信任根(如BootROM中的密钥)进行签名或哈希锁定。
常见误区
- 误区一:私钥存储在构建服务器明文目录。应使用HSM或加密的密钥库。
- 误区二:签名算法选择不当。RSA-PSS比PKCS#1 v1.5更安全,但兼容性需评估。
- 误区三:忽略签名验证的失败处理。必须实现fail-stop机制,而非仅记录日志后继续启动。
3.3 证书体系:构建可管理的信任链
核心原理
直接使用单一公钥进行验证虽然简单,但缺乏灵活性。当密钥泄露或需要轮换时,必须更新所有设备的公钥。证书体系通过X.509证书将公钥与身份信息绑定,并由证书颁发机构(CA)签名。在安全启动中,典型的信任链为:根CA证书(存储在ROM)→ 平台密钥(PK)→ 密钥交换密钥(KEK)→ 签名数据库(db)。UEFI安全启动即采用此模型。
证书链验证流程
- 信任锚:设备内置根CA证书,其公钥哈希烧录在eFuse中。
- 逐级验证:验证PK证书由根CA签名,KEK证书由PK签名,db中的签名证书由KEK签名。
- 镜像验证:镜像签名必须与db中的某个证书匹配,或由db中证书对应的私钥签名。
- 撤销处理:通过dbx(禁止签名数据库)列出已撤销的证书或哈希。
风险提示:证书链的每一环都是攻击面。如果根CA私钥泄露,整个信任体系崩溃。因此,根CA私钥必须离线存储,并采用多方分持(Shamir秘密共享)策略。同时,证书有效期管理至关重要,过期证书会导致设备无法启动。
案例拆解:UEFI安全启动证书轮换
某PC厂商需要更新平台密钥(PK),但已出货设备无法物理访问。方案设计如下:
- 约束条件:设备处于UEFI安全启动模式,不允许关闭安全启动。
- 操作流程:通过已签名的更新工具,使用旧PK私钥对新PK证书进行签名,生成PK更新证书。
- 验证机制:UEFI固件验证新PK证书由旧PK签名,且新证书的生效时间在旧证书有效期之后。
- 结果:设备成功更新PK,且安全启动状态保持开启。
此案例的关键在于证书轮换协议的设计,必须确保旧密钥在过渡期内仍然可信,同时新密钥能够无缝接管。
常见误区
- 误区一:证书链过长导致启动时间增加。每级证书验证都需要RSA运算,应控制链长在3-4级以内。
- 误区二:忽略证书撤销列表(CRL)的更新。在离线设备中,CRL可能无法及时更新,需采用黑名单哈希方式。
- 误区三:将证书文件存储在可写介质。证书本身必须存储在受保护的Flash区域,或由固件签名保护。
3.4 密码学组件在安全启动中的协同工作
核心原理
安全启动的信任链是逐级哈希校验 + 逐级签名验证的组合。每一级引导加载程序都包含下一级镜像的公钥或证书,并执行以下操作:
- 计算下一级镜像的哈希值。
- 使用内置公钥验证镜像的数字签名。
- 验证通过后,将控制权移交给下一级。
- 同时传递信任度量值(如TPM PCR扩展)。
信任链设计模式
| 层级 | 信任根 | 验证对象 | 密码学操作 |
|---|---|---|---|
| BootROM | eFuse中的根公钥哈希 | SPL / U-Boot | SHA-256 + RSA验证 |
| SPL | BootROM传递的公钥 | U-Boot / ATF | SHA-256 + ECC验证 |
| U-Boot | 设备树中的公钥 | 内核 / 设备树 | FIT签名验证 |
| 内核 | 内核内置密钥环 | 内核模块 / 驱动 | 模块签名验证 |
案例拆解:ARM Trusted Firmware (ATF) 启动链
在ARMv8平台,ATF定义了从BL1(BootROM)到BL31(EL3运行时固件)的完整信任链。具体流程:
- BL1:验证BL2的哈希和签名,BL2的证书由平台根密钥签发。
- BL2:验证BL31和BL33(U-Boot)的镜像,使用Trusted Board Boot (TBB) 流程。
- BL31:在EL3运行,负责安全监控调用,并验证BL33的启动。
该设计的关键在于证书链的静态验证:BL2使用fiptool工具生成FIP镜像,包含所有BL镜像及其证书。验证时,BL1使用存储在ROM中的ROTPK(根密钥公钥)验证BL2证书链。
常见误区与总结
- 误区一:认为安全启动是“一刀切”的开关。实际需要根据威胁模型选择信任根位置和验证强度。
- 误区二:忽略防回滚机制。即使签名验证通过,攻击者仍可重放旧版本镜像。必须结合单调计数器或版本号检查。
- 误区三:将密码学运算全部放在CPU上。应使用硬件加速器(如ARM CryptoCell、Intel QAT)减少启动时间开销。
总结复盘:安全启动的密码学设计不是简单堆砌算法,而是需要系统化思考:哈希解决“镜像是否被改”,签名解决“镜像是否来自可信方”,证书解决“公钥如何安全分发和轮换”,信任根解决“第一把钥匙放在哪里”。四者缺一不可,且必须与硬件安全特性(eFuse、TPM、TEE)深度结合。在实际项目中,建议先明确信任边界和威胁模型,再选择合适的密码学组合,最后通过渗透测试验证整个链路的健壮性。