第3章 TEE中的密钥生成:硬件安全密钥派生、平台身份密钥与密封密钥
好,咱们进入第三章。前两章我们把TEE的基本概念和签名验签的宏观流程聊清楚了。这一章,我带你钻到TEE的肚子里,看看那些用来签名的密钥到底是怎么生出来的。
说实话,密钥生成这事儿,在普通操作系统里可能就是个随机数加个算法。但在TEE里,规矩多得很。为什么?因为TEE的核心理念就是——密钥必须出生在硬件里,死在硬件里。密钥一旦被软件拿到明文,那TEE的信任根基就塌了。
我个人习惯把TEE的密钥体系分成三个层次:根密钥、平台身份密钥、应用密封密钥。咱们一个一个来拆。
3.1 硬件安全密钥派生:从芯片熔丝到派生密钥
所有TEE密钥的源头,是一组在芯片制造时烧录的硬件根密钥。这玩意儿通常存在eFuse(电子熔丝)或OTP(一次性可编程)存储器里。芯片一出厂,这组值就焊死了,谁也改不了。
但问题来了——我们不能直接用这个根密钥去签名每一个消息。为什么?
- 安全隔离:根密钥一旦泄露,整个芯片的信任体系全完蛋。
- 功能单一:根密钥通常只有128位或256位,没法满足不同场景的密钥需求。
- 合规要求:很多安全标准(比如FIPS 140-3)要求密钥必须定期更换或派生,不能直接用硬件固定密钥。
所以,TEE的做法是:用根密钥作为种子,通过硬件支持的密钥派生函数(KDF),派生出各种用途的密钥。
这里我放一张图,帮你理解这个派生链条:
你看,整个派生链条是单向的。从根密钥到AIK,从AIK到应用密钥,每一步都经过硬件KDF。我在项目里见过有人试图在REE侧自己算派生密钥,结果被安全审计打了个大大的X——派生过程必须在TEE内部完成,这是铁律。
核心原则:TEE密钥派生遵循"最小权限"原则——每个密钥只做一件事,只在一个上下文中可用。根密钥只做派生,不直接用于签名或加密。
3.2 平台身份密钥(AIK):TEE的身份证
平台身份密钥,英文叫Attestation Identity Key,简称AIK。这玩意儿是TEE在远程证明中的身份证。
你想想看,当你的TEE向远程服务器证明"我是合法的TEE"时,总得有个东西来签名吧?这个签名者就是AIK。
AIK有几个关键特性:
- 唯一性:每个TEE实例的AIK都是唯一的,由芯片根密钥派生而来。
- 不可导出性:AIK的私钥永远不能离开TEE。你只能用它签名,不能把它读出来。
- 可验证性:AIK的公钥会通过证书链发布,远程方可以验证。
AIK的生成流程,我拆成几步:
- 读取平台配置:TEE启动时,硬件测量其代码、配置、数据,生成一组度量值(Measurement)。
- 调用硬件KDF:以根密钥为种子,以平台度量值为输入,调用硬件KDF。
- 生成AIK密钥对:KDF的输出作为种子,生成非对称密钥对(通常是RSA-2048或ECDSA-P256)。
- 签发AIK证书:由平台制造商或隐私CA(Certificate Authority)对AIK公钥签名,形成证书链。
这里有个坑,我踩过。有一次,我在调试远程证明时,发现AIK签名总是验证失败。查了两天,最后发现是平台度量值在两次启动之间发生了变化——因为固件升级了。AIK的生成依赖度量值,度量值变了,AIK就变了。所以,AIK不是永久不变的,它跟平台状态绑定。
避坑指南:AIK的生成时机很关键。我建议在TEE初始化阶段就生成AIK,并缓存其公钥证书。不要在每次远程证明时都重新生成AIK,那样性能太差。但要注意,如果平台度量值发生变化(比如固件升级),必须重新生成AIK。
3.3 密封密钥(Sealing Key):数据保险箱的锁
密封密钥,Sealing Key,这名字起得好——就像把数据封在一个信封里,只有特定条件下才能打开。
密封密钥的用途很直接:加密数据,让数据只能在指定的TEE状态下解密。
举个例子:你的TEE应用有一个私密配置文件,你希望只有在你当前这个TEE版本下才能读取。怎么办?用密封密钥加密它。
密封密钥的生成机制和AIK类似,但有一个关键区别:
| 特性 | AIK | Sealing Key |
|---|---|---|
| 用途 | 远程证明签名 | 数据加密保护 |
| 派生输入 | 平台度量值 + 根密钥 | 平台度量值 + 应用标识 + 根密钥 |
| 密钥类型 | 非对称密钥对 | 对称密钥(AES-256) |
| 可导出性 | 私钥不可导出,公钥可导出 | 完全不可导出 |
| 生命周期 | 随平台状态变化 | 随应用和平台状态变化 |
你看,Sealing Key的派生输入多了一个应用标识。这意味着,不同应用拿到的密封密钥是不同的。即使同一个TEE,应用A的密封密钥也解不开应用B加密的数据。
密封密钥的使用流程是这样的:
- 密封(Seal):应用调用TEE的密封接口,传入明文数据和期望的平台状态。TEE内部生成Sealing Key,加密数据,输出密文。
- 解封(Unseal):应用调用解封接口,传入密文。TEE检查当前平台状态是否匹配,如果匹配则重新生成Sealing Key并解密,否则拒绝。
经验之谈:我在做金融支付方案时,经常用密封密钥来保护交易密钥。具体做法是:在TEE初始化时,生成一个交易主密钥,然后用密封密钥加密后存储到REE的文件系统中。每次需要使用时,再解封出来。这样既保证了密钥的持久化,又确保了安全性——因为解封条件可以设置得非常严格,比如要求TEE版本号、应用哈希值完全匹配。
3.4 密钥生命周期管理
密钥生出来了,不是就完事了。你得管好它的整个生命周期。
我总结了一个密钥生命周期管理的清单:
- 生成:在TEE内部,使用硬件KDF,确保随机性足够。
- 使用:限制使用次数和上下文,比如AIK只能用于签名,不能用于加密。
- 存储:私钥永远留在TEE内,公钥可以导出但需要证书保护。
- 轮换:定期更换密钥,尤其是应用密钥。我建议最长不超过一年。
- 销毁:当TEE被重置或应用被卸载时,必须安全擦除密钥。
这里要特别强调密钥轮换。我记得有一次做安全审计,客户问:"你们的AIK多久换一次?"我说:"AIK跟平台状态绑定,平台不变就不换。"审计员直接打了个问号。后来我才明白,即使平台状态不变,也应该定期重新生成AIK,以防止长期使用同一密钥带来的泄露风险。
最佳实践:对于AIK,建议在每次远程证明会话开始时重新生成一次。对于Sealing Key,建议在应用每次启动时重新密封数据,这样Sealing Key实际上每次都在变化。虽然密钥本身变了,但只要解封条件不变,数据就能正常解密。
3.5 小结
好,这一章的内容就这些。总结一下:
- TEE的密钥体系从硬件根密钥开始,通过KDF派生。
- AIK是TEE的身份证,用于远程证明签名,依赖平台度量值。
- Sealing Key是数据保险箱的锁,用于加密保护数据,依赖平台状态和应用标识。
- 密钥生命周期管理要覆盖生成、使用、存储、轮换、销毁五个环节。
嗯,这些概念听起来可能有点抽象。但等你真正动手做TEE开发时,你会发现——密钥生成是所有安全功能的基石。根密钥稳了,派生密钥对了,后面的签名验签才能站得住脚。