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,下面挂载各种子密钥。每个子密钥又可以挂载下一级密钥。这种设计的好处是:权限隔离——不同应用使用不同分支,互不干扰。
我画了一张图,帮你理解这个层次关系:
从图中你能看到,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策略会话实现:
- 策略PCR:验证安全启动PCR值
- 策略授权:验证USB令牌中的秘密
- 策略OR:两个条件同时满足才放行
4.4.3 授权策略的“坑”
我曾经踩过的坑:策略会话有超时机制。默认情况下,策略会话在TPM空闲一段时间后自动失效。我在一个项目中没注意这个,结果系统运行几小时后,所有策略授权都失败,服务崩溃。解决方案是:在策略会话中定期执行PolicyRestart,或者使用持久化策略会话。
4.5 密钥生命周期管理
密钥不是创建完就完事了。在实际运维中,你需要管理密钥的整个生命周期:
| 阶段 | 操作 | 注意事项 |
|---|---|---|
| 创建 | TPM2_Create + TPM2_Load | 选择合适的算法和授权策略 |
| 使用 | TPM2_Sign / TPM2_Unseal | 确保会话未过期 |
| 备份 | TPM2_Duplicate | 只能在父子密钥之间迁移 |
| 销毁 | TPM2_EvictControl | 持久密钥需要特殊权限 |
| 轮换 | 创建新密钥替换旧密钥 | 旧数据需要重新加密 |
我的习惯:每次创建密钥时,我都会在TPM的NV索引中记录密钥的元数据——创建时间、算法、用途、授权策略哈希。这样后期审计时,能快速定位每个密钥的来龙去脉。你想想看,如果密钥泄露了,连它是什么时候创建的都不知道,怎么追溯?
好了,TPM密钥体系的核心内容就这些。记住一句话:持久密钥是根基,会话密钥是工具,授权策略是锁。理解这三者的关系,你就能设计出安全的TPM应用方案。