当前位置:首页 > 系统教程 > 正文

KDF+AES-256-CBC加密解密实战

KDF+AES-256-CBC加密解密实战

用同一份seed在Linux与OP-TEE/TA间互通

在安全敏感的应用中,经常需要将加密解密操作放在可信执行环境(如OP-TEE)中执行,而普通世界(Linux)负责业务逻辑。如何保证两端使用完全相同的密钥对同一份数据进行加解密?答案就是使用相同的种子(seed)通过KDF派生密钥。本文带你一步步实现KDF + AES-256-CBC在Linux和OP-TEE TA之间的互通,小白也能看懂!

KDF+AES-256-CBC加密解密实战 KDF  AES-256-CBC OP-TEE TA 加密解密互通 第1张

🔐 核心概念

  • KDF(密钥派生函数):从一段秘密种子(seed)派生出符合长度要求的密钥,常用算法有HKDF、PBKDF2。本文采用HKDF-SHA256。
  • AES-256-CBC:一种对称加密算法,密钥长度256位,CBC模式需要初始化向量IV,填充方式为PKCS#7。
  • OP-TEE TA:运行在安全世界的可信应用,通过GP TEE Internal API执行安全操作。
  • 加密解密互通:保证Linux端加密的数据可以被TA解密,反之亦然,关键是KDF参数和AES参数完全一致。

📌 环境准备

Linux端:Python 3.8+,安装pycryptodome库(用于AES和HKDF)。 OP-TEE端:使用QEMU模拟环境或开发板,编写TA时需包含,利用TEE_CipherInit等函数。

🧪 实战步骤

  1. 约定KDF参数:双方使用HKDF-SHA256,seed为固定16字节(例如0x01,0x02,...),info字段设为"aes-256-cbc-key",salt可选但需一致。
  2. Linux端派生密钥并加密:使用Python的HKDF派生32字节密钥,生成随机IV,对明文进行AES-256-CBC加密,输出IV+Ciphertext。
  3. OP-TEE TA端派生密钥并解密:TA接收seed和IV+密文,调用TEE_DeriveKey从seed派生相同密钥,再用TEE_CipherInit等API解密。
  4. 验证互通:将Linux加密的结果传给TA解密,若还原出明文则成功。

🐧 Linux端代码示例(Python)

from Crypto.Protocol.KDF import HKDFfrom Crypto.Cipher import AESfrom Crypto.Hash import SHA256import osseed = bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,              0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10])info = b"aes-256-cbc-key"key = HKDF(seed, 32, salt=None, hashmod=SHA256, context=info)iv = os.urandom(16)cipher = AES.new(key, AES.MODE_CBC, iv)plaintext = b"Hello, OP-TEE! This is a secret message."# 填充到16的倍数pad_len = 16 - (len(plaintext) % 16)plaintext_padded = plaintext + bytes([pad_len]) * pad_lenciphertext = cipher.encrypt(plaintext_padded)result = iv + ciphertext   # 传递给TAprint("密钥:", key.hex())print("密文(IV+Cipher):", result.hex())

🛡️ OP-TEE TA端代码片段(C语言)

#include TEE_Result decrypt_with_seed(void *seed, size_t seed_len,                              void *iv_cipher, size_t iv_cipher_len,                              void *plain, size_t *plain_len) {    TEE_ObjectHandle hkdf_handle = TEE_HANDLE_NULL;    TEE_ObjectHandle aes_key = TEE_HANDLE_NULL;    TEE_OperationHandle op = TEE_HANDLE_NULL;    uint8_t derived_key[32];    size_t key_size = sizeof(derived_key);    uint8_t *iv = iv_cipher;    uint8_t *cipher = iv_cipher + 16;    size_t cipher_len = iv_cipher_len - 16;        // 1. 派生密钥 (使用TEE DeriveKey API,需要先导入seed作为HKDF的密钥)    TEE_AllocateOperation(&op, TEE_ALG_HKDF_SHA256, TEE_MODE_DERIVE, 0);    TEE_AllocateTransientObject(TEE_TYPE_HKDF_OK, seed_len*8, &hkdf_handle);    TEE_InitRefAttribute(seed, seed_len); // 简化:实际需要设置属性    TEE_PopulateTransientObject(hkdf_handle, ...);    TEE_SetOperationKey(op, hkdf_handle);    TEE_DeriveKey(op, NULL, -1, derived_key, &key_size); // 派生密钥        // 2. 导入AES密钥    TEE_AllocateTransientObject(TEE_TYPE_AES, 256, &aes_key);    TEE_InitRefAttribute(derived_key, key_size);    TEE_PopulateTransientObject(aes_key, ...);    TEE_AllocateOperation(&op, TEE_ALG_AES_CBC_PKCS7, TEE_MODE_DECRYPT, 0);    TEE_SetOperationKey(op, aes_key);    TEE_CipherInit(op, iv, 16);    TEE_CipherUpdate(op, cipher, cipher_len, plain, plain_len);    TEE_CipherDoFinal(op, NULL, 0, NULL, 0);        // 清理资源...    return TEE_SUCCESS;}

⚠️ 注意事项:

  • 双方必须使用完全相同的KDF算法、seed、info和salt,否则密钥不同。
  • IV必须随机且每次不同,但需要随密文一起传输给解密方。
  • 填充模式均使用PKCS#7,OP-TEE的TEE_ALG_AES_CBC_PKCS7自动处理。
  • 在大端/小端问题上,seed和info的字节序必须一致,建议固定为字节数组。

🎯 总结

通过统一的KDF参数和AES-256-CBC配置,可以轻松实现Linux与OP-TEE TA之间的加密解密互通。关键在于仔细对齐所有密码学参数,包括算法、密钥长度、IV处理、填充方式。本文提供的实战示例可帮助开发者快速搭建跨世界安全通信的基础。未来还可以扩展为使用更安全的认证加密模式(如GCM),但KDF + AES-256-CBC的组合已经能满足大多数保密性需求。

—— 文章关键词:KDF, AES-256-CBC, OP-TEE TA, 加密解密互通 ——