信任根与信任链:硬件信任根(TPM、TEE)、信任链建立过程、静态与动态信任根

聊远程证明,绕不开一个核心问题:凭什么相信你?

设备说“我是安全的”,你得有办法验证。这个验证的起点,就是信任根。我做了这么多年物联网安全,见过太多设备因为信任根没扎牢,整个安全体系形同虚设。说白了,信任根就是整个安全大厦的地基,地基不稳,上面盖多高都没用。

2.1 什么是信任根?

信任根(Root of Trust,RoT),是一个必须被无条件信任的组件。它本身不能被验证,因为它是验证链条的起点。你想想看,如果信任根还需要别的组件来验证它,那就不叫“根”了。

在实际项目中,信任根通常是一个硬件安全模块。为什么必须是硬件?因为纯软件方案容易被篡改。我见过一个客户,早期用软件模拟TPM,结果被攻击者直接patch了内存里的度量值,整个信任链瞬间崩塌。从那以后,我对纯软件信任根一直持保留态度。

信任根的核心属性:

  • 不可伪造性:攻击者无法冒充信任根的行为
  • 防篡改性:信任根自身的代码和数据不能被修改
  • 隔离性:信任根运行在独立的安全环境中,主CPU无法直接访问其内部状态

2.2 硬件信任根:TPM vs TEE

目前主流的硬件信任根方案有两种:TPM 和 TEE。很多人搞不清它们的区别,我简单说说。

2.2.1 TPM(可信平台模块)

TPM 是一个独立的安全芯片,有自己独立的CPU、存储和密码运算单元。它跟主CPU是分离的,通过LPC或SPI总线通信。

TPM 的核心能力包括:

  • 平台配置寄存器(PCR):用于存储度量值的哈希,一旦写入就不能被篡改(只能扩展)
  • 背书密钥(EK):每个TPM芯片出厂时烧录的唯一身份密钥
  • 存储根密钥(SRK):保护用户数据的根密钥
  • 单调计数器:防止回滚攻击

我记得有一次做车联网项目,需要保证每个T-Box的固件不被篡改。我们就是用TPM的PCR来存储每个启动阶段的度量值,然后远程证明时直接读取PCR值。攻击者就算改了Flash里的固件,PCR里的哈希对不上,立马现原形。

2.2.2 TEE(可信执行环境)

TEE 跟 TPM 思路不同。它不是在主芯片外面加一个独立芯片,而是在主CPU内部划出一个安全区域。这个区域有独立的地址空间、独立的中断处理,甚至独立的IO路径。

常见的TEE实现:

  • ARM TrustZone:把CPU分为安全世界和普通世界
  • Intel SGX:在内存中创建飞地(Enclave)
  • RISC-V 物理内存保护(PMP):通过硬件规则隔离内存区域

TEE 的好处是性能好,因为它跟主CPU共享计算资源,不需要额外的芯片。但坏处是,如果主CPU本身有硬件漏洞,TEE也保不住。嗯,这里要注意,TEE的安全假设是“CPU硬件是可信的”,这个假设在某些场景下不一定成立。

对比维度 TPM TEE
物理形态 独立芯片 CPU内部安全区域
性能 较低(独立芯片,通信有延迟) 较高(共享CPU资源)
安全隔离 物理隔离,抗物理攻击强 逻辑隔离,抗物理攻击弱
成本 较高(额外芯片和PCB面积) 较低(集成在SoC内)
典型应用 PC、服务器、工业设备 手机、IoT设备、边缘计算

2.3 信任链建立过程

有了信任根,接下来就是怎么把信任从根传递到整个系统。这个过程叫信任链(Chain of Trust)。

信任链的核心思想很简单:每一级在启动下一级之前,先度量下一级的代码,然后把度量值存到信任根里,最后才把控制权交给下一级。

2.3.1 典型的信任链流程

  1. 阶段1:信任根(Boot ROM)
    • 上电后CPU首先执行固化在ROM里的代码
    • 这段代码是硬件写死的,不可修改
    • 它度量Bootloader的代码,计算哈希,写入TPM的PCR[0]
  2. 阶段2:Bootloader
    • Boot ROM验证通过后,跳转到Bootloader
    • Bootloader度量OS内核,写入PCR[1]
  3. 阶段3:OS内核
    • 内核度量关键系统服务,写入PCR[2]
  4. 阶段4:应用层
    • 系统服务度量应用程序,写入PCR[3]

我曾经在一个IoT网关项目里,发现Bootloader没有度量内核的签名,而是直接度量了整个内核镜像文件。结果攻击者往内核镜像里塞了一段恶意代码,虽然哈希变了,但攻击者同时修改了Bootloader的度量逻辑,让它跳过校验。这就是典型的信任链断裂——度量者本身没有被度量。

避坑指南:信任链的每一级都必须度量下一级的完整代码和关键配置,不能只度量部分内容。我曾经见过一个方案,Bootloader只度量了内核的头部,结果攻击者修改了内核的尾部代码,绕过了度量。记住:度量范围必须是“执行前能访问到的所有可执行内容”。

2.4 静态信任根 vs 动态信任根

信任根根据其生命周期,可以分为静态信任根和动态信任根。这个区分很重要,直接决定了你的远程证明方案能覆盖多广。

2.4.1 静态信任根(SRoT)

静态信任根在设备上电时建立,之后在整个运行期间保持不变。它通常固化在Boot ROM里,从设备启动开始就参与信任链的构建。

特点:

  • 信任根在设备生命周期内不变
  • 只能度量启动时的系统状态
  • 无法应对运行时的动态攻击(如代码注入、内存篡改)

说白了,静态信任根只能保证“启动时是干净的”,但启动之后系统被黑了,它管不了。

2.4.2 动态信任根(DRoT)

动态信任根可以在设备运行过程中随时建立新的信任锚点。它不依赖启动时的信任链,而是通过硬件指令在任意时刻创建一个可信环境。

典型的实现:

  • Intel TXT(Trusted Execution Technology):通过GETSEC指令在运行时启动一个可信度量
  • ARM TrustZone 动态建立安全世界:通过SMC指令切换到安全世界,重新度量关键代码
  • TPM 2.0 的“授权策略”:允许在运行时动态扩展PCR

动态信任根的好处是,你可以按需建立信任。比如,当系统检测到可疑行为时,可以动态启动一个安全环境,重新度量关键内存区域,然后跟远程证明服务器通信。

对比维度 静态信任根(SRoT) 动态信任根(DRoT)
建立时机 设备上电时 运行过程中任意时刻
信任锚点 Boot ROM(不可变) 硬件指令或安全监控器
覆盖范围 启动过程 启动过程 + 运行时
抗运行时攻击 弱 强
实现复杂度 低 高
典型场景 简单IoT设备、传感器 边缘服务器、自动驾驶域控制器

我的建议:如果你的设备资源受限(比如MCU只有几百KB Flash),用静态信任根就够了。但如果是高性能设备(比如带Linux的网关),我强烈建议引入动态信任根。原因很简单——静态信任根只能证明“启动时是好的”,但攻击者完全可以在系统运行后注入恶意代码。动态信任根让你能在运行时重新建立信任,这才是远程证明真正需要的。

2.5 信任根与信任链的关系图

下面这张图展示了信任根如何通过信任链,把信任从硬件层传递到应用层。注意看,每一级都在度量下一级,度量值最终汇总到信任根里。

信任根与信任链架构图 信任根与信任链架构 信任根(Boot ROM / TPM) Bootloader(度量内核) OS内核(度量系统服务) 系统服务(度量应用程序) 应用程序 度量值流向 每级度量结果写入 TPM的PCR寄存器 或TEE的安全存储 信任传递方向 从信任根开始 逐级向下传递 静态信任根 仅在上电时建立 信任链固定不变 无法应对运行时攻击 动态信任根 运行时按需建立 可重新度量关键代码 抗运行时注入攻击 信任链:每一级度量下一级,度量值存入信任根,控制权逐级传递

2.6 实际项目中的选择建议

讲了这么多,到底怎么选?我根据自己的项目经验,给几个实用建议:

  • 低端MCU设备(Cortex-M0/M3,Flash < 1MB):用静态信任根 + 片上Boot ROM。TPM太贵,TEE不支持,老老实实做启动度量就够了。
  • 中端Linux设备(Cortex-A系列,带MMU):用TEE(TrustZone)作为信任根。性能好,成本可控,支持动态信任根。
  • 高端服务器/边缘节点(x86/ARMv8):TPM + TEE 双保险。TPM做静态信任根,TEE做动态信任根,互相补充。
  • 车规级设备:必须用独立HSM(硬件安全模块),同时支持静态和动态信任根。车规要求ISO 21434,对信任链有严格规定。

特别提醒:不要为了省成本砍掉信任根。我见过一个智能门锁项目,为了省几毛钱没用安全芯片,结果被攻击者通过SPI接口直接dump了Flash,拿到了所有用户的指纹模板。事后复盘,如果当时加一颗TPM,成本增加不到2块钱,但整个安全等级能提升一个数量级。信任根不是成本,是保险。