4. TPM密钥体系:持久密钥、会话密钥与授权策略

TPM的密钥体系,说白了就是一套“谁能碰什么数据”的权限管理系统。我刚开始接触TPM时,觉得密钥层次结构特别绕——SRK、EK、会话密钥,一堆缩写。后来在项目中踩过几次坑,才真正理解这套设计有多精妙。

4.1 持久密钥:TPM的“根”

持久密钥是TPM出厂时就存在或首次初始化时生成的,它们几乎不离开TPM芯片。我个人习惯把持久密钥分成两类:身份类和存储类。

4.1.1 背书密钥(EK)

EK是TPM的“身份证”。每个TPM芯片只有一个EK,它在生产时生成,或者由平台厂商注入。EK的私钥永远不出TPM,只用于解密和签名。

EK的核心用途:

  • 远程证明时,向挑战方证明“我是合法TPM”
  • 建立安全会话时,解密对方发来的对称密钥
  • 生成身份密钥(AIK)时的信任锚点

注意:EK是敏感资产。我曾经见过一个项目,直接把EK证书暴露在日志里,结果被攻击者追踪到设备身份。EK证书可以公开,但EK私钥必须锁死在TPM内。

4.1.2 存储根密钥(SRK)

SRK是TPM存储体系的“天花板”。所有用户创建的密钥,最终都受SRK保护。SRK在TPM所有者设置时生成,默认使用RSA-2048或ECC-256。

SRK的授权策略很关键。默认情况下,SRK不需要密码——嗯,这里要注意,很多开发者以为SRK必须设密码,其实TPM 2.0允许SRK使用空授权。但我在实际项目中强烈建议:生产环境必须给SRK设置授权值或策略,否则一旦攻击者拿到物理访问权限,可以直接用SRK解密所有存储密钥。

属性 EK SRK
生成时机 出厂时或首次启动 TPM所有者设置时
数量 1个 1个(可更换)
主要用途 身份证明 保护存储密钥
授权策略 通常无授权 空授权或策略授权
能否导出 不能 不能

4.2 会话密钥:临时“通行证”

会话密钥是TPM与外部实体(比如应用程序)之间建立的临时对称密钥。它们生命周期短,用完就销毁。我习惯把会话密钥比作“一次性门禁卡”——每次进出都换一张。

TPM 2.0支持三种会话类型:

  • HMAC会话:用于命令授权和参数加密。我最常用这种,因为它兼容性好。
  • 策略会话:用于复杂授权场景,比如需要多个条件同时满足才能使用密钥。
  • 审计会话:记录TPM命令执行日志,用于事后追溯。

实战技巧:我在做安全启动方案时,每次开机都会建立一个新的HMAC会话,用于加载密钥。会话用完立即FlushContext,避免残留。你想想看,如果会话密钥泄露,攻击者就能伪装成合法应用操作TPM。

4.3 密钥层次结构

TPM 2.0的密钥层次结构,其实是一棵树。根是SRK,下面挂载各种子密钥。每个子密钥又可以挂载下一级密钥。这种设计的好处是:权限隔离——不同应用使用不同分支,互不干扰。

我画了一张图,帮你理解这个层次关系:

TPM 2.0 密钥层次结构 SRK(存储根密钥) 应用A存储密钥 应用B存储密钥 平台存储密钥 签名密钥 加密密钥 身份密钥(AIK) 派生密钥 关键说明 • 每个子密钥都受父密钥加密保护 • 叶子密钥是实际业务使用的密钥 • 删除父密钥会导致所有子密钥不可用 • 不同应用使用独立分支,实现权限隔离

从图中你能看到,SRK是唯一不依赖其他密钥的“根”。每个子密钥都受父密钥加密保护。删除父密钥,所有子密钥就废了——我曾经在测试时手抖删了SRK,结果整个TPM存储区报废,只能重新初始化。

4.4 密钥授权策略

授权策略是TPM 2.0最强大的特性之一。TPM 1.2只有简单的密码授权,而2.0引入了策略会话(Policy Session),可以实现非常灵活的访问控制。

4.4.1 密码授权

最简单的方式。创建密钥时设置一个密码,使用时提供相同密码即可。适合低安全场景。

// 创建带密码授权的存储密钥
TPM2B_AUTH authValue = { .size = 6, .buffer = "123456" };
TPM2B_SENSITIVE_CREATE sensitive = {
    .sensitive = {
        .userAuth = authValue,
        .data = { .size = 0 }
    }
};
// 后续使用必须提供相同密码

4.4.2 策略授权

这才是TPM 2.0的精华。策略授权允许你定义一组条件,只有满足所有条件才能使用密钥。常见的策略包括:

  • PCR值匹配:只有系统处于特定状态(如安全启动完成)才能使用密钥
  • 物理存在:需要用户物理按下按钮确认
  • 时间窗口:只能在指定时间段内使用
  • 多因素组合:同时需要密码+PCR匹配+物理存在

实战案例:我做过一个磁盘加密方案,要求只有在系统安全启动成功、且用户插入特定USB令牌时,才能释放解密密钥。用TPM策略会话实现:

  1. 策略PCR:验证安全启动PCR值
  2. 策略授权:验证USB令牌中的秘密
  3. 策略OR:两个条件同时满足才放行

4.4.3 授权策略的“坑”

我曾经踩过的坑:策略会话有超时机制。默认情况下,策略会话在TPM空闲一段时间后自动失效。我在一个项目中没注意这个,结果系统运行几小时后,所有策略授权都失败,服务崩溃。解决方案是:在策略会话中定期执行PolicyRestart,或者使用持久化策略会话。

4.5 密钥生命周期管理

密钥不是创建完就完事了。在实际运维中,你需要管理密钥的整个生命周期:

阶段 操作 注意事项
创建 TPM2_Create + TPM2_Load 选择合适的算法和授权策略
使用 TPM2_Sign / TPM2_Unseal 确保会话未过期
备份 TPM2_Duplicate 只能在父子密钥之间迁移
销毁 TPM2_EvictControl 持久密钥需要特殊权限
轮换 创建新密钥替换旧密钥 旧数据需要重新加密

我的习惯:每次创建密钥时,我都会在TPM的NV索引中记录密钥的元数据——创建时间、算法、用途、授权策略哈希。这样后期审计时,能快速定位每个密钥的来龙去脉。你想想看,如果密钥泄露了,连它是什么时候创建的都不知道,怎么追溯?

好了,TPM密钥体系的核心内容就这些。记住一句话:持久密钥是根基,会话密钥是工具,授权策略是锁。理解这三者的关系,你就能设计出安全的TPM应用方案。