本文目录导读:

在可信执行环境(TEE,如Intel SGX、ARM TrustZone、AMD SEV等)中派生密钥,核心目标是利用TEE提供的硬件隔离和远程验证能力,确保密钥的生成、存储和使用过程对操作系统、Hypervisor及其他特权软件不可见,以下是通用的技术流程和关键步骤:
基础架构:TEE中的密钥派生层级
TEE内部通常维护一个 硬件根密钥(Root Key),它被安全地存储在CPU的熔丝(fuse)或一次性可编程(OTP)存储器中,永不泄露,所有派生密钥都基于此根密钥,通过单向函数(如HKDF)生成。
通用派生流程(以Intel SGX为例)
步骤1:建立安全上下文
- 程序加载到TEE的Enclave(飞地)中,TEE会验证代码的完整性(通过MRENCLAVE度量值)。
- Enclave内部通过 ECALL(Enter Call) 接口与外部未信任环境通信。
步骤2:获取平台绑定密钥
TEE内部使用 平台身份密钥(Platform Identity Key) 或 Sealing Key(封印密钥)。
- SGX提供
sgx_create_seal_key()或直接通过硬件指令EGETKEY获取一个 Sealing Key,该密钥绑定到特定的Enclave(通过其度量值)和CPU平台。 - 派生公式示例:
Sealing Key = KDF(Root Key, Enclave度量值 || Platform Policy)
KDF通常是HMAC-SHA256。
步骤3:从Sealing Key派生用户级密钥
由于Sealing Key是平台相关的,若要派生出更细粒度的应用密钥,需引入 用户自定义熵:
# 伪代码示例 root_key = get_sealing_key_from_tee() # TEE内部获取 salt = generate_random_32_bytes() # 从TEE硬件随机数生成器获取 context = b"my-app-key-v1" # 自定义上下文字符串 derived_key = HKDF_expand(root_key, salt, context, output_length=32)
- 关键点:
salt和context应在TEE内部生成或通过安全通道注入,防止外部篡改。
步骤4:对外提供加密接口
TEE不应直接暴露派生密钥的明文,而是提供 黑盒操作接口:
tee_encrypt(plaintext, key_id)-> ciphertexttee_decrypt(ciphertext, key_id)-> plaintext
这样外部仅看到密文,密钥永远不出TEE。
关键安全设计考量
1 远程验证(Remote Attestation)
- 在将密钥材料注入TEE之前,外部信任方需通过 远程验证 确认TEE运行的是预期代码且未被篡改。
- 通常使用挑战-响应协议,TEE生成一份由硬件签名的 报价(Quote),包含度量值和公钥。
2 抗重放与绑定
- 密钥绑定到TEE状态:派生密钥时使用当前Enclave的度量值,确保不同版本的代码派生出的密钥不同(防止代码降级攻击)。
- 防回滚:部分TEE支持单调计数器(Monotonic Counter),可绑定密钥到特定“世代”。
3 密钥生命周期管理
- 持久化安全存储:将Sealing Key加密后的派生密钥存储在外部磁盘,密钥恢复时重新使用同一Sealing Key解密。
- 动态更新:如需定期更换密钥,可在TEE内部使用
key_update(旧派生密钥, 新随机数)生成新密钥,旧密钥立即销毁。
不同TEE的差异
| TEE类型 | 密钥派生API | 特殊注意点 |
|---|---|---|
| Intel SGX | EGETKEY 指令获取Sealing Key;sgx_ra_get_keys 用于远程认证密钥 |
需要处理EPC内存限制(如128MB) |
| ARM TrustZone | 通过 Secure Monitor Call (SMC) 与OP-TEE或Trusty OS交互 | 密钥派生在安全世界完成,使用硬件RNG |
| AMD SEV | 使用 AMD Key Management Server (KMS) 导出的KDK(密钥派生密钥) | 更多用于虚拟机加密,需结合特定SEV命令 |
| RISC-V Keystone | 软件定义TEE,需自行实现KDF模块 | 可灵活使用硬件RISC-V Crypto扩展 |
风险与缓解
- 侧信道攻击:派生过程需注意常数时间实现,避免基于缓存或分支的时序泄露。
- 密钥混淆:多个Enclave共享同一平台时,确保不同Enclave的Sealing Key不同(通过不同的度量值自然隔离)。
- 确定性随机数:始终使用TEE提供的 硬件随机数生成器(HRNG),而非软件随机源。
实际代码示例(基于SGX SDK)
sgx_status_t derive_app_key(sgx_ec256_private_t *out_key) {
sgx_seal_key_t seal_key;
// 1. 获取绑定当前Enclave的Sealing Key
sgx_create_seal_key(NULL, NULL, &seal_key);
// 2. 使用HKDF派生(需自己实现KDF或调用Intel IPP)
uint8_t salt[32];
sgx_read_rand(salt, 32); // TEE硬件熵源
// 3. HKDF-SHA256(salt, seal_key, "app-defined-context")
hkdf_sha256_extract_expand(seal_key, salt, "my-app-v2", out_key);
// 4. 清理临时敏感数据
memset_s(&seal_key, sizeof(seal_key), 0, sizeof(seal_key));
return SGX_SUCCESS;
}
在TEE中派生密钥的核心是:利用硬件根密钥 -> 通过KDF绑定到TEE代码/平台身份 -> 结合用户熵生成应用密钥,整个过程中,密钥材料在TEE密码边界之外永不可见,对外只提供加密/解密等操作接口,实际工程中,需要结合远程验证、单调计数器、安全存储等机制共同构建完整的密钥管理体系。