使用HKDF进行密钥派生(C/C++)
对应算法规格请查看密钥派生算法规格:HKDF。
开发步骤
-
调用OH_CryptoKdfParams_Create,指定字符串参数'HKDF',创建密钥派生参数对象。
-
调用OH_CryptoKdfParams_SetParam,设置HKDF所需的参数。示例如下:
- CRYPTO_KDF_KEY_DATABLOB:用于生成派生密钥的原始密钥材料。
- CRYPTO_KDF_SALT_DATABLOB:盐值。
- CRYPTO_KDF_INFO_DATABLOB:应用程序特定的信息(可选)。
-
调用OH_CryptoKdf_Create,指定字符串参数'HKDF|SHA256|EXTRACT_AND_EXPAND',创建密钥派生函数对象。
-
调用OH_CryptoKdf_Derive,指定目标密钥的字节长度,进行密钥派生。
#include "CryptoArchitectureKit/crypto_architecture_kit.h"
#include <cstdio>
#include <cstring>
#include "file.h"
static OH_Crypto_ErrCode setParams(OH_CryptoKdfParams **params)
{
const char *keyData = "012345678901234567890123456789";
Crypto_DataBlob key = {
.data = reinterpret_cast<uint8_t *>(const_cast<char *>(keyData)),
.len = strlen(keyData)
};
OH_Crypto_ErrCode ret = OH_CryptoKdfParams_SetParam(*params, CRYPTO_KDF_KEY_DATABLOB, &key);
if (ret != CRYPTO_SUCCESS) {
goto end;
}
// 设置盐值。
const char *saltData = "saltstring";
Crypto_DataBlob salt = {
.data = reinterpret_cast<uint8_t *>(const_cast<char *>(saltData)),
.len = strlen(saltData)
};
ret = OH_CryptoKdfParams_SetParam(*params, CRYPTO_KDF_SALT_DATABLOB, &salt);
if (ret != CRYPTO_SUCCESS) {
goto end;
}
// 设置应用程序特定信息(可选)。
const char *infoData = "infostring";
Crypto_DataBlob info = {
.data = reinterpret_cast<uint8_t *>(const_cast<char *>(infoData)),
.len = strlen(infoData)
};
ret = OH_CryptoKdfParams_SetParam(*params, CRYPTO_KDF_INFO_DATABLOB, &info);
if (ret != CRYPTO_SUCCESS) {
goto end;
}
end:
OH_CryptoKdfParams_Destroy(*params);
*params = nullptr;
return ret;
}
OH_Crypto_ErrCode doTestHkdf()
{
// 创建HKDF参数对象。
OH_CryptoKdfParams *params = nullptr;
OH_Crypto_ErrCode ret = OH_CryptoKdfParams_Create("HKDF", ¶ms);
if (ret != CRYPTO_SUCCESS) {
return ret;
}
ret = setParams(¶ms);
if (ret != CRYPTO_SUCCESS) {
return ret;
}
// 创建密钥派生函数对象。
OH_CryptoKdf *kdfCtx = nullptr;
ret = OH_CryptoKdf_Create("HKDF|SHA256|EXTRACT_AND_EXPAND", &kdfCtx);
if (ret != CRYPTO_SUCCESS) {
OH_CryptoKdfParams_Destroy(params);
return ret;
}
// 派生密钥。
Crypto_DataBlob out = {0};
uint32_t keyLength = 32; // 生成32字节的密钥。
ret = OH_CryptoKdf_Derive(kdfCtx, params, keyLength, &out);
if (ret != CRYPTO_SUCCESS) {
OH_CryptoKdf_Destroy(kdfCtx);
OH_CryptoKdfParams_Destroy(params);
return ret;
}
printf("Derived key length: %u\n", out.len);
// 清理资源。
OH_Crypto_FreeDataBlob(&out);
OH_CryptoKdf_Destroy(kdfCtx);
OH_CryptoKdfParams_Destroy(params);
return CRYPTO_SUCCESS;
}