加密導(dǎo)入密鑰(C/C++)
以加密導(dǎo)入ECDH密鑰對(duì)為例,涉及業(yè)務(wù)側(cè)加密密鑰的[密鑰生成]、[協(xié)商]等操作不在本示例中體現(xiàn)。
在CMake腳本中鏈接相關(guān)動(dòng)態(tài)庫
target_link_libraries(entry PUBLIC libhuks_ndk.z.so)
開發(fā)步驟
- 設(shè)備A(導(dǎo)入設(shè)備)將待導(dǎo)入密鑰轉(zhuǎn)換成[HUKS密鑰材料格式]To_Import_Key(僅針對(duì)非對(duì)稱密鑰,若待導(dǎo)入密鑰是對(duì)稱密鑰則可省略此步驟)。
- 設(shè)備B(被導(dǎo)入設(shè)備)生成一個(gè)加密導(dǎo)入用途的、用于協(xié)商的非對(duì)稱密鑰對(duì)Wrapping_Key(公鑰Wrapping_Pk,私鑰Wrapping_Sk),其密鑰用途設(shè)置為unwrap,導(dǎo)出Wrapping_Key的公鑰材料Wrapping_Pk并保存。
- 設(shè)備A使用和設(shè)備B同樣的算法,生成一個(gè)加密導(dǎo)入用途的、用于協(xié)商的非對(duì)稱密鑰對(duì)Caller_Key(公鑰Caller_Pk,私鑰Caller_Sk),導(dǎo)出Caller_Key的公鑰材料Caller_Pk并保存。
- 設(shè)備A生成一個(gè)對(duì)稱密鑰Caller_Kek,該密鑰后續(xù)將用于加密To_Import_Key。
- 設(shè)備A基于Caller_Key的私鑰Caller_Sk和設(shè)備B Wrapping_Key的公鑰Wrapping_Pk,協(xié)商出Shared_Key。
- 設(shè)備A使用Caller_Kek加密To_Import_Key,生成To_Import_Key_Enc。
- 設(shè)備A使用Shared_Key加密Caller_Kek,生成Caller_Kek_Enc。
- 設(shè)備A封裝Caller_Pk、Caller_Kek_Enc、To_Import_Key_Enc等加密導(dǎo)入的密鑰材料并發(fā)送給設(shè)備B,加密導(dǎo)入密鑰材料格式見[加密導(dǎo)入密鑰材料格式]。
- 設(shè)備B導(dǎo)入封裝的加密密鑰材料。
- 設(shè)備A、B刪除用于加密導(dǎo)入的密鑰。
- 開發(fā)前請(qǐng)熟悉鴻蒙開發(fā)指導(dǎo)文檔 :[
gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
#include "napi/native_api.h"
#include "huks/native_huks_api.h"
#include "huks/native_huks_param.h"
#include < algorithm >
OH_Huks_Result InitParamSet(struct OH_Huks_ParamSet **paramSet, const struct OH_Huks_Param *params,
uint32_t paramCount) {
OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet);
if (ret.errorCode != OH_HUKS_SUCCESS) {
return ret;
}
ret = OH_Huks_AddParams(*paramSet, params, paramCount);
if (ret.errorCode != OH_HUKS_SUCCESS) {
OH_Huks_FreeParamSet(paramSet);
return ret;
}
ret = OH_Huks_BuildParamSet(paramSet);
if (ret.errorCode != OH_HUKS_SUCCESS) {
OH_Huks_FreeParamSet(paramSet);
return ret;
}
return ret;
}
struct HksImportWrappedKeyTestParams {
// server key, for real
struct OH_Huks_Blob *wrappingKeyAlias;
struct OH_Huks_ParamSet *genWrappingKeyParamSet;
uint32_t publicKeySize;
struct OH_Huks_Blob *callerKeyAlias;
struct OH_Huks_ParamSet *genCallerKeyParamSet;
struct OH_Huks_Blob *callerKekAlias;
struct OH_Huks_Blob *callerKek;
struct OH_Huks_ParamSet *importCallerKekParamSet;
struct OH_Huks_Blob *callerAgreeKeyAlias;
struct OH_Huks_ParamSet *agreeParamSet;
struct OH_Huks_ParamSet *importWrappedKeyParamSet;
struct OH_Huks_Blob *importedKeyAlias;
struct OH_Huks_Blob *importedPlainKey;
uint32_t keyMaterialLen;
};
static const uint32_t IV_SIZE = 16;
static uint8_t IV[IV_SIZE] = "bababababababab"; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
static const uint32_t WRAPPED_KEY_IV_SIZE = 16;
static uint8_t WRAPPED_KEY_IV[IV_SIZE] = "bababababababab"; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
static const uint32_t AAD_SIZE = 16;
static uint8_t AAD[AAD_SIZE] = "abababababababa"; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
static const uint32_t NONCE_SIZE = 12;
static uint8_t NONCE[NONCE_SIZE] = "hahahahahah"; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
static const uint32_t AEAD_TAG_SIZE = 16;
static const uint32_t X25519_256_SIZE = 256;
static struct OH_Huks_Blob g_wrappingKeyAliasAes256 = {.size = (uint32_t)strlen("test_wrappingKey_x25519_aes256"),
.data = (uint8_t *)"test_wrappingKey_x25519_aes256"};
static struct OH_Huks_Blob g_callerKeyAliasAes256 = {.size = (uint32_t)strlen("test_caller_key_x25519_aes256"),
.data = (uint8_t *)"test_caller_key_x25519_aes256"};
static struct OH_Huks_Blob g_callerKekAliasAes256 = {.size = (uint32_t)strlen("test_caller_kek_x25519_aes256"),
.data = (uint8_t *)"test_caller_kek_x25519_aes256"};
static struct OH_Huks_Blob g_callerAes256Kek = {.size = (uint32_t)strlen("This is kek to encrypt plain key"),
.data = (uint8_t *)"This is kek to encrypt plain key"};
static struct OH_Huks_Blob g_callerAgreeKeyAliasAes256 = {.size =
(uint32_t)strlen("test_caller_agree_key_x25519_aes256"),
.data = (uint8_t *)"test_caller_agree_key_x25519_aes256"};
static struct OH_Huks_Blob g_importedKeyAliasAes256 = {.size = (uint32_t)strlen("test_import_key_x25519_aes256"),
.data = (uint8_t *)"test_import_key_x25519_aes256"};
static struct OH_Huks_Blob g_importedAes256PlainKey = {.size = (uint32_t)strlen("This is plain key to be imported"),
.data = (uint8_t *)"This is plain key to be imported"};
static struct OH_Huks_Param g_importWrappedAes256Params[] = {
{.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
{.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT | OH_HUKS_KEY_PURPOSE_DECRYPT},
{.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
{.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
{.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
{.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
{.tag = OH_HUKS_TAG_UNWRAP_ALGORITHM_SUITE, .uint32Param = OH_HUKS_UNWRAP_SUITE_X25519_AES_256_GCM_NOPADDING},
{.tag = OH_HUKS_TAG_ASSOCIATED_DATA,
.blob = {.size = AAD_SIZE, .data = (uint8_t *)AAD}}, // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值應(yīng)與調(diào)用者信息相關(guān)
{.tag = OH_HUKS_TAG_NONCE,
.blob = {.size = NONCE_SIZE, .data = (uint8_t *)NONCE}}}; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
static const uint32_t g_x25519PubKeySize = 32;
static struct OH_Huks_Param g_genWrappingKeyParams[] = {
{.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_X25519},
{.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_UNWRAP},
{.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_CURVE25519_KEY_SIZE_256}};
static struct OH_Huks_Param g_genCallerX25519Params[] = {
{.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_X25519},
{.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE},
{.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_CURVE25519_KEY_SIZE_256}};
static struct OH_Huks_Param g_importParamsCallerKek[] = {
{.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
{.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
{.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
{.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
{.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
{.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
{.tag = OH_HUKS_TAG_IV,
.blob = {.size = WRAPPED_KEY_IV_SIZE,
.data = (uint8_t *)WRAPPED_KEY_IV}}}; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
static struct OH_Huks_Param g_callerAgreeParams[] = {
{.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_X25519},
{.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_AGREE},
{.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_CURVE25519_KEY_SIZE_256}};
static struct OH_Huks_Param g_aesKekEncryptParams[] = {
{.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
{.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
{.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
{.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
{.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
{.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
{.tag = OH_HUKS_TAG_ASSOCIATED_DATA,
.blob = {.size = AAD_SIZE, .data = (uint8_t *)AAD}}, // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值應(yīng)與調(diào)用者信息相關(guān)
{.tag = OH_HUKS_TAG_NONCE,
.blob = {.size = NONCE_SIZE, .data = (uint8_t *)NONCE}}}; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
static struct OH_Huks_Param g_importAgreeKeyParams[] = {
{.tag = OH_HUKS_TAG_ALGORITHM, .uint32Param = OH_HUKS_ALG_AES},
{.tag = OH_HUKS_TAG_PURPOSE, .uint32Param = OH_HUKS_KEY_PURPOSE_ENCRYPT},
{.tag = OH_HUKS_TAG_KEY_SIZE, .uint32Param = OH_HUKS_AES_KEY_SIZE_256},
{.tag = OH_HUKS_TAG_PADDING, .uint32Param = OH_HUKS_PADDING_NONE},
{.tag = OH_HUKS_TAG_BLOCK_MODE, .uint32Param = OH_HUKS_MODE_GCM},
{.tag = OH_HUKS_TAG_DIGEST, .uint32Param = OH_HUKS_DIGEST_NONE},
{.tag = OH_HUKS_TAG_IV,
.blob = {.size = IV_SIZE, .data = (uint8_t *)IV}}}; // 此處僅為測(cè)試數(shù)據(jù),實(shí)際使用時(shí)該值每次應(yīng)該不同
OH_Huks_Result HuksAgreeKey(const struct OH_Huks_ParamSet *paramSet, const struct OH_Huks_Blob *keyAlias,
const struct OH_Huks_Blob *peerPublicKey, struct OH_Huks_Blob *agreedKey) {
uint8_t temp[10] = {0};
struct OH_Huks_Blob inData = {sizeof(temp), temp};
uint8_t handleU[sizeof(uint64_t)] = {0};
struct OH_Huks_Blob handle = {sizeof(uint64_t), handleU};
OH_Huks_Result ret = OH_Huks_InitSession(keyAlias, paramSet, &handle, nullptr);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
uint8_t outDataU[1024] = {0};
struct OH_Huks_Blob outDataUpdate = {1024, outDataU};
ret = OH_Huks_UpdateSession(&handle, paramSet, peerPublicKey, &outDataUpdate);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = OH_Huks_FinishSession(&handle, paramSet, &inData, agreedKey);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
return ret;
}
OH_Huks_Result MallocAndCheckBlobData(struct OH_Huks_Blob *blob, const uint32_t blobSize) {
struct OH_Huks_Result ret;
ret.errorCode = OH_HUKS_SUCCESS;
blob- >data = (uint8_t *)malloc(blobSize);
if (blob- >data == NULL) {
ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
}
return ret;
}
static const uint32_t TIMES = 4;
static const uint32_t MAX_UPDATE_SIZE = 64;
static const uint32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES;
#define HUKS_FREE_BLOB(blob)
do {
if ((blob).data != nullptr) {
free((blob).data);
(blob).data = nullptr;
}
(blob).size = 0;
} while (0)
#define OH_HUKS_KEY_BYTES(keySize) (((keySize) + 7) / 8)
static OH_Huks_Result HksEncryptLoopUpdate(const struct OH_Huks_Blob *handle, const struct OH_Huks_ParamSet *paramSet,
const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *outData) {
struct OH_Huks_Result ret;
ret.errorCode = OH_HUKS_SUCCESS;
struct OH_Huks_Blob inDataSeg = *inData;
uint8_t *lastPtr = inData- >data + inData- >size - 1;
struct OH_Huks_Blob outDataSeg = {MAX_OUTDATA_SIZE, NULL};
uint8_t *cur = outData- >data;
outData- >size = 0;
inDataSeg.size = MAX_UPDATE_SIZE;
bool isFinished = false;
while (inDataSeg.data <= lastPtr) {
if (inDataSeg.data + MAX_UPDATE_SIZE <= lastPtr) {
outDataSeg.size = MAX_OUTDATA_SIZE;
} else {
isFinished = true;
inDataSeg.size = lastPtr - inDataSeg.data + 1;
break;
}
if (MallocAndCheckBlobData(&outDataSeg, outDataSeg.size).errorCode != (int32_t)OH_HUKS_SUCCESS) {
ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
return ret;
}
ret = OH_Huks_UpdateSession(handle, paramSet, &inDataSeg, &outDataSeg);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
free(outDataSeg.data);
return ret;
}
std::copy(outDataSeg.data, outDataSeg.data + outDataSeg.size, cur);
cur += outDataSeg.size;
outData- >size += outDataSeg.size;
free(outDataSeg.data);
if ((isFinished == false) && (inDataSeg.data + MAX_UPDATE_SIZE > lastPtr)) {
ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
return ret;
}
inDataSeg.data += MAX_UPDATE_SIZE;
}
struct OH_Huks_Blob outDataFinish = {inDataSeg.size * TIMES, NULL};
if (MallocAndCheckBlobData(&outDataFinish, outDataFinish.size).errorCode != (int32_t)OH_HUKS_SUCCESS) {
ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
return ret;
}
ret = OH_Huks_FinishSession(handle, paramSet, &inDataSeg, &outDataFinish);
if (ret.errorCode != OH_HUKS_SUCCESS) {
free(outDataFinish.data);
return ret;
}
std::copy(outDataFinish.data, outDataFinish.data + outDataFinish.size, cur);
outData- >size += outDataFinish.size;
free(outDataFinish.data);
return ret;
}
OH_Huks_Result HuksEncrypt(const struct OH_Huks_Blob *key, const struct OH_Huks_ParamSet *paramSet,
const struct OH_Huks_Blob *plainText, struct OH_Huks_Blob *cipherText) {
uint8_t handle[sizeof(uint64_t)] = {0};
struct OH_Huks_Blob handleBlob = {sizeof(uint64_t), handle};
OH_Huks_Result ret = OH_Huks_InitSession(key, paramSet, &handleBlob, nullptr);
if (ret.errorCode != OH_HUKS_SUCCESS) {
return ret;
}
ret = HksEncryptLoopUpdate(&handleBlob, paramSet, plainText, cipherText);
return ret;
}
static OH_Huks_Result BuildWrappedKeyData(struct OH_Huks_Blob **blobArray, uint32_t size,
struct OH_Huks_Blob *outData) {
uint32_t totalLength = size * sizeof(uint32_t);
struct OH_Huks_Result ret;
ret.errorCode = OH_HUKS_SUCCESS;
/* 計(jì)算大小 */
for (uint32_t i = 0; i < size; ++i) {
totalLength += blobArray[i]- >size;
}
struct OH_Huks_Blob outBlob = {0, nullptr};
outBlob.size = totalLength;
ret = MallocAndCheckBlobData(&outBlob, outBlob.size);
if (ret.errorCode != OH_HUKS_SUCCESS) {
return ret;
}
uint32_t offset = 0;
/* 拷貝數(shù)據(jù) */
for (uint32_t i = 0; i < size; ++i) {
if (totalLength - offset >= sizeof(blobArray[i]- >size)) {
std::copy(reinterpret_cast< uint8_t * >(&blobArray[i]- >size),
reinterpret_cast< uint8_t * >(&blobArray[i]- >size) + sizeof(blobArray[i]- >size),
outBlob.data + offset);
} else {
ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
return ret;
}
offset += sizeof(blobArray[i]- >size);
if (totalLength - offset >= blobArray[i]- >size) {
std::copy(blobArray[i]- >data, blobArray[i]- >data + blobArray[i]- >size, outBlob.data + offset);
} else {
ret.errorCode = OH_HUKS_ERR_CODE_INTERNAL_ERROR;
return ret;
}
offset += blobArray[i]- >size;
}
outData- >size = outBlob.size;
outData- >data = outBlob.data;
return ret;
}
static OH_Huks_Result CheckParamsValid(const struct HksImportWrappedKeyTestParams *params) {
struct OH_Huks_Result ret;
ret.errorCode = OH_HUKS_SUCCESS;
if (params == nullptr) {
ret.errorCode = OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT;
return ret;
}
if (params- >wrappingKeyAlias == nullptr || params- >genWrappingKeyParamSet == nullptr ||
params- >callerKeyAlias == nullptr || params- >genCallerKeyParamSet == nullptr ||
params- >callerKekAlias == nullptr || params- >callerKek == nullptr ||
params- >importCallerKekParamSet == nullptr || params- >callerAgreeKeyAlias == nullptr ||
params- >agreeParamSet == nullptr || params- >importWrappedKeyParamSet == nullptr ||
params- >importedKeyAlias == nullptr || params- >importedPlainKey == nullptr) {
ret.errorCode = OH_HUKS_ERR_CODE_ILLEGAL_ARGUMENT;
return ret;
}
return ret;
}
static OH_Huks_Result GenerateAndExportHuksPublicKey(const struct HksImportWrappedKeyTestParams *params,
struct OH_Huks_Blob *huksPublicKey) {
OH_Huks_Result ret = OH_Huks_GenerateKeyItem(params- >wrappingKeyAlias, params- >genWrappingKeyParamSet, nullptr);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
huksPublicKey- >size = params- >publicKeySize;
ret = MallocAndCheckBlobData(huksPublicKey, huksPublicKey- >size);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = OH_Huks_ExportPublicKeyItem(params- >wrappingKeyAlias, nullptr, huksPublicKey);
return ret;
}
static OH_Huks_Result GenerateAndExportCallerPublicKey(const struct HksImportWrappedKeyTestParams *params,
struct OH_Huks_Blob *callerSelfPublicKey) {
OH_Huks_Result ret = OH_Huks_GenerateKeyItem(params- >callerKeyAlias, params- >genCallerKeyParamSet, nullptr);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
callerSelfPublicKey- >size = params- >publicKeySize;
ret = MallocAndCheckBlobData(callerSelfPublicKey, callerSelfPublicKey- >size);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = OH_Huks_ExportPublicKeyItem(params- >callerKeyAlias, params- >genWrappingKeyParamSet, callerSelfPublicKey);
return ret;
}
static OH_Huks_Result ImportKekAndAgreeSharedSecret(const struct HksImportWrappedKeyTestParams *params,
const struct OH_Huks_Blob *huksPublicKey,
struct OH_Huks_Blob *outSharedKey) {
OH_Huks_Result ret =
OH_Huks_ImportKeyItem(params- >callerKekAlias, params- >importCallerKekParamSet, params- >callerKek);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = MallocAndCheckBlobData(outSharedKey, outSharedKey- >size);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = HuksAgreeKey(params- >agreeParamSet, params- >callerKeyAlias, huksPublicKey, outSharedKey);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
struct OH_Huks_ParamSet *importAgreeKeyParams = nullptr;
ret = InitParamSet(&importAgreeKeyParams, g_importAgreeKeyParams,
sizeof(g_importAgreeKeyParams) / sizeof(OH_Huks_Param));
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = OH_Huks_ImportKeyItem(params- >callerAgreeKeyAlias, importAgreeKeyParams, outSharedKey);
OH_Huks_FreeParamSet(&importAgreeKeyParams);
return ret;
}
static OH_Huks_Result EncryptImportedPlainKeyAndKek(const struct HksImportWrappedKeyTestParams *params,
struct OH_Huks_Blob *plainCipherText,
struct OH_Huks_Blob *kekCipherText) {
struct OH_Huks_ParamSet *encryptParamSet = nullptr;
OH_Huks_Result ret =
InitParamSet(&encryptParamSet, g_aesKekEncryptParams, sizeof(g_aesKekEncryptParams) / sizeof(OH_Huks_Param));
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = HuksEncrypt(params- >callerKekAlias, encryptParamSet, params- >importedPlainKey, plainCipherText);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = HuksEncrypt(params- >callerAgreeKeyAlias, encryptParamSet, params- >callerKek, kekCipherText);
OH_Huks_FreeParamSet(&encryptParamSet);
return ret;
}
static OH_Huks_Result ImportWrappedKey(const struct HksImportWrappedKeyTestParams *params,
struct OH_Huks_Blob *plainCipher, struct OH_Huks_Blob *kekCipherText,
struct OH_Huks_Blob *peerPublicKey, struct OH_Huks_Blob *wrappedKeyData) {
struct OH_Huks_Blob commonAad = {.size = AAD_SIZE, .data = reinterpret_cast< uint8_t * >(AAD)};
struct OH_Huks_Blob commonNonce = {.size = NONCE_SIZE, .data = reinterpret_cast< uint8_t * >(NONCE)};
struct OH_Huks_Blob keyMaterialLen = {.size = sizeof(uint32_t), .data = (uint8_t *)¶ms- >keyMaterialLen};
/* 從密文中拷貝AEAD的tag并縮小其大小 */
const uint32_t tagSize = AEAD_TAG_SIZE;
uint8_t kekTagBuf[tagSize] = {0};
struct OH_Huks_Blob kekTag = {.size = tagSize, .data = kekTagBuf};
std::copy(plainCipher- >data + (plainCipher- >size - tagSize),
plainCipher- >data + (plainCipher- >size - tagSize) + tagSize, kekTag.data);
plainCipher- >size -= tagSize;
/* 從密鑰加密密鑰的密文中拷貝AEAD的tag并縮小其大小 */
uint8_t agreeKeyTagBuf[tagSize] = {0};
struct OH_Huks_Blob agreeKeyTag = {.size = tagSize, .data = agreeKeyTagBuf};
std::copy(kekCipherText- >data + (kekCipherText- >size - tagSize),
kekCipherText- >data + (kekCipherText- >size - tagSize) + tagSize, agreeKeyTagBuf);
kekCipherText- >size -= tagSize;
struct OH_Huks_Blob *blobArray[] = {peerPublicKey, &commonAad, &commonNonce, &agreeKeyTag, kekCipherText,
&commonAad, &commonNonce, &kekTag, &keyMaterialLen, plainCipher};
OH_Huks_Result ret = BuildWrappedKeyData(blobArray, OH_HUKS_IMPORT_WRAPPED_KEY_TOTAL_BLOBS, wrappedKeyData);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
struct OH_Huks_Param *purpose = nullptr;
ret = OH_Huks_GetParam(params- >importWrappedKeyParamSet, OH_HUKS_TAG_PURPOSE, &purpose);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
ret = OH_Huks_ImportWrappedKeyItem(params- >importedKeyAlias, params- >wrappingKeyAlias,
params- >importWrappedKeyParamSet, wrappedKeyData);
return ret;
}
OH_Huks_Result HksImportWrappedKeyTestCommonCase(const struct HksImportWrappedKeyTestParams *params) {
OH_Huks_Result ret = CheckParamsValid(params);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return ret;
}
struct OH_Huks_Blob huksPublicKey = {0, nullptr};
struct OH_Huks_Blob callerSelfPublicKey = {0, nullptr};
struct OH_Huks_Blob outSharedKey = {.size = OH_HUKS_KEY_BYTES(OH_HUKS_AES_KEY_SIZE_256), .data = nullptr};
struct OH_Huks_Blob wrappedKeyData = {0, nullptr};
uint8_t plainKeyCipherBuffer[OH_HUKS_MAX_KEY_SIZE] = {0};
struct OH_Huks_Blob plainCipherText = {OH_HUKS_MAX_KEY_SIZE, plainKeyCipherBuffer};
uint8_t kekCipherTextBuffer[OH_HUKS_MAX_KEY_SIZE] = {0};
struct OH_Huks_Blob kekCipherText = {OH_HUKS_MAX_KEY_SIZE, kekCipherTextBuffer};
/* 模擬加密導(dǎo)入密鑰場(chǎng)景,設(shè)備A為遠(yuǎn)端設(shè)備(導(dǎo)入設(shè)備),設(shè)備B為本端設(shè)備(被導(dǎo)入設(shè)備) */
do {
/**
* 1.設(shè)備A將待導(dǎo)入密鑰轉(zhuǎn)換成HUKS密鑰材料格式To_Import_Key(僅針對(duì)非對(duì)稱密鑰,若待導(dǎo)入密鑰是對(duì)稱密鑰則可省略此步驟),
* 本示例使用g_importedAes256PlainKey(對(duì)稱密鑰)作為模擬
*/
/* 2.設(shè)備B生成一個(gè)加密導(dǎo)入用途的、用于協(xié)商的非對(duì)稱密鑰對(duì)Wrapping_Key(公鑰Wrapping_Pk,私鑰Wrapping_Sk),其密鑰用途設(shè)置為unwrap,導(dǎo)出Wrapping_Key公鑰Wrapping_Pk存放在變量huksPublicKey中
*/
ret = GenerateAndExportHuksPublicKey(params, &huksPublicKey);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
break;
}
/* 3.設(shè)備A使用和設(shè)備B同樣的算法,生成一個(gè)加密導(dǎo)入用途的、用于協(xié)商的非對(duì)稱密鑰對(duì)Caller_Key(公鑰Caller_Pk,私鑰Caller_Sk),導(dǎo)出Caller_Key公鑰Caller_Pk存放在變量callerSelfPublicKey中
*/
ret = GenerateAndExportCallerPublicKey(params, &callerSelfPublicKey);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
break;
}
/**
* 4. 設(shè)備A生成一個(gè)對(duì)稱密鑰Caller_Kek,該密鑰后續(xù)將用于加密To_Import_Key
* 5. 設(shè)備A基于Caller_Key的私鑰Caller_Sk和設(shè)備B Wrapping_Key的公鑰Wrapping_Pk,協(xié)商出Shared_Key
*/
ret = ImportKekAndAgreeSharedSecret(params, &huksPublicKey, &outSharedKey);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
break;
}
/**
* 6. 設(shè)備A使用Caller_Kek加密To_Import_Key,生成To_Import_Key_Enc
* 7. 設(shè)備A使用Shared_Key加密Caller_Kek,生成Caller_Kek_Enc
*/
ret = EncryptImportedPlainKeyAndKek(params, &plainCipherText, &kekCipherText);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
break;
}
/* 8. 設(shè)備A封裝Caller_Pk、To_Import_Key_Enc、Caller_Kek_Enc等加密導(dǎo)入的材料并發(fā)送給設(shè)備B。
* 本示例作為變量存放在callerSelfPublicKey,plainCipherText,kekCipherText
* 9. 設(shè)備B導(dǎo)入封裝的加密密鑰材料
*/
ret = ImportWrappedKey(params, &plainCipherText, &kekCipherText, &callerSelfPublicKey, &wrappedKeyData);
} while (0);
/* 10. 設(shè)備A、B刪除用于加密導(dǎo)入的密鑰 */
HUKS_FREE_BLOB(huksPublicKey);
HUKS_FREE_BLOB(callerSelfPublicKey);
HUKS_FREE_BLOB(outSharedKey);
HUKS_FREE_BLOB(wrappedKeyData);
return ret;
}
void HksClearKeysForWrappedKeyTest(const struct HksImportWrappedKeyTestParams *params) {
OH_Huks_Result ret = CheckParamsValid(params);
if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {
return;
}
(void)OH_Huks_DeleteKeyItem(params- >wrappingKeyAlias, nullptr);
(void)OH_Huks_DeleteKeyItem(params- >callerKeyAlias, nullptr);
(void)OH_Huks_DeleteKeyItem(params- >callerKekAlias, nullptr);
(void)OH_Huks_DeleteKeyItem(params- >callerAgreeKeyAlias, nullptr);
(void)OH_Huks_DeleteKeyItem(params- >importedKeyAlias, nullptr);
}
static OH_Huks_Result InitCommonTestParamsAndDoImport(struct HksImportWrappedKeyTestParams *importWrappedKeyTestParams,
const struct OH_Huks_Param *importedKeyParamSetArray,
uint32_t arraySize) {
struct OH_Huks_ParamSet *genX25519KeyParamSet = nullptr;
struct OH_Huks_ParamSet *genCallerKeyParamSet = nullptr;
struct OH_Huks_ParamSet *callerImportParamsKek = nullptr;
struct OH_Huks_ParamSet *agreeParamSet = nullptr;
struct OH_Huks_ParamSet *importPlainKeyParams = nullptr;
OH_Huks_Result ret;
do {
ret = InitParamSet(&genX25519KeyParamSet, g_genWrappingKeyParams,
sizeof(g_genWrappingKeyParams) / sizeof(OH_Huks_Param));
if (ret.errorCode != OH_HUKS_SUCCESS) {
break;
}
importWrappedKeyTestParams- >genWrappingKeyParamSet = genX25519KeyParamSet;
importWrappedKeyTestParams- >publicKeySize = g_x25519PubKeySize;
ret = InitParamSet(&genCallerKeyParamSet, g_genCallerX25519Params,
sizeof(g_genCallerX25519Params) / sizeof(OH_Huks_Param));
if (ret.errorCode != OH_HUKS_SUCCESS) {
break;
}
importWrappedKeyTestParams- >genCallerKeyParamSet = genCallerKeyParamSet;
ret = InitParamSet(&callerImportParamsKek, g_importParamsCallerKek,
sizeof(g_importParamsCallerKek) / sizeof(OH_Huks_Param));
if (ret.errorCode != OH_HUKS_SUCCESS) {
break;
}
importWrappedKeyTestParams- >importCallerKekParamSet = callerImportParamsKek;
ret = InitParamSet(&agreeParamSet, g_callerAgreeParams, sizeof(g_callerAgreeParams) / sizeof(OH_Huks_Param));
if (ret.errorCode != OH_HUKS_SUCCESS) {
break;
}
importWrappedKeyTestParams- >agreeParamSet = agreeParamSet;
ret = InitParamSet(&importPlainKeyParams, importedKeyParamSetArray, arraySize);
if (ret.errorCode != OH_HUKS_SUCCESS) {
break;
}
importWrappedKeyTestParams- >importWrappedKeyParamSet = importPlainKeyParams;
ret = HksImportWrappedKeyTestCommonCase(importWrappedKeyTestParams);
} while (0);
OH_Huks_FreeParamSet(&genX25519KeyParamSet);
OH_Huks_FreeParamSet(&genCallerKeyParamSet);
OH_Huks_FreeParamSet(&callerImportParamsKek);
OH_Huks_FreeParamSet(&agreeParamSet);
OH_Huks_FreeParamSet(&importPlainKeyParams);
return ret;
}
static napi_value ImportWrappedKey(napi_env env, napi_callback_info info) {
struct HksImportWrappedKeyTestParams importWrappedKeyTestParams001 = {0};
importWrappedKeyTestParams001.wrappingKeyAlias = &g_wrappingKeyAliasAes256;
importWrappedKeyTestParams001.keyMaterialLen = g_importedAes256PlainKey.size;
importWrappedKeyTestParams001.callerKeyAlias = &g_callerKeyAliasAes256;
importWrappedKeyTestParams001.callerKekAlias = &g_callerKekAliasAes256;
importWrappedKeyTestParams001.callerKek = &g_callerAes256Kek;
importWrappedKeyTestParams001.callerAgreeKeyAlias = &g_callerAgreeKeyAliasAes256;
importWrappedKeyTestParams001.importedKeyAlias = &g_importedKeyAliasAes256;
importWrappedKeyTestParams001.importedPlainKey = &g_importedAes256PlainKey;
OH_Huks_Result ohResult =
InitCommonTestParamsAndDoImport(&importWrappedKeyTestParams001, g_importWrappedAes256Params,
sizeof(g_importWrappedAes256Params) / sizeof(struct OH_Huks_Param));
HksClearKeysForWrappedKeyTest(&importWrappedKeyTestParams001);
napi_value ret;
napi_create_int32(env, ohResult.errorCode, &ret);
return ret;
}
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
調(diào)測(cè)驗(yàn)證
調(diào)用[OH_Huks_IsKeyItemExist]驗(yàn)證密鑰是否存在,如密鑰存在即表示密鑰導(dǎo)入成功。
#include "huks/native_huks_api.h"
#include "huks/native_huks_param.h"
#include < string.h >
static napi_value IsKeyExist(napi_env env, napi_callback_info info)
{
/* 1.指定密鑰別名 */
struct OH_Huks_Blob keyAlias = {
(uint32_t)strlen("test_key"),
(uint8_t *)"test_key"
};
/* 2.調(diào)用OH_Huks_IsKeyItemExist判斷密鑰是否存在 */
struct OH_Huks_Result ohResult = OH_Huks_IsKeyItemExist(&keyAlias, NULL);
if (ohResult.errorCode != OH_HUKS_SUCCESS) {
// 失敗
} else {
// 成功
}
}
審核編輯 黃宇
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。
舉報(bào)投訴
-
C++
+關(guān)注
關(guān)注
22文章
2108瀏覽量
73657 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2352瀏覽量
42863
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù)簡(jiǎn)介
Universal Keystore Kit(密鑰管理服務(wù),下述簡(jiǎn)稱為HUKS)向業(yè)務(wù)/應(yīng)用提供
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 生成密鑰C、C++
以生成ECC密鑰為例,生成隨機(jī)密鑰。具體的場(chǎng)景介紹及支持的算法規(guī)格。
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 密鑰導(dǎo)入介紹及算法規(guī)格
如果業(yè)務(wù)在HUKS外部生成密鑰(比如應(yīng)用間協(xié)商生成、服務(wù)器端生成),業(yè)務(wù)可以將密鑰導(dǎo)入到HUKS中由HUKS進(jìn)行管理。
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 明文導(dǎo)入密鑰 ArkTS
分別以導(dǎo)入AES256與RSA2048密鑰為例,具體的場(chǎng)景介紹及支持的算法規(guī)格
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 明文導(dǎo)入密鑰C、C++
以明文導(dǎo)入ECC密鑰為例。具體的場(chǎng)景介紹及支持的算法規(guī)格
鴻蒙開發(fā):Universal Keystore Kit 密鑰管理服務(wù) 加密導(dǎo)入密鑰 ArkTS
以加密導(dǎo)入ECDH密鑰對(duì)為例,涉及業(yè)務(wù)側(cè)加密密鑰的[密鑰生成]、[協(xié)商])等操作不在本示例中體現(xiàn)。
鴻蒙開發(fā):Universal Keystore Kit 密鑰管理服務(wù) 密鑰協(xié)商 C、C++
以協(xié)商密鑰類型為ECDH,并密鑰僅在HUKS內(nèi)使用為例,完成密鑰協(xié)商。具體的場(chǎng)景介紹及支持的算法規(guī)格,請(qǐng)參考[密鑰生成支持的算法]。
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 密鑰派生C、C++
以HKDF256密鑰為例,完成密鑰派生。具體的場(chǎng)景介紹及支持的算法規(guī)格,請(qǐng)參考[密鑰生成支持的算法]。
鴻蒙開發(fā):Universal Keystore Kit 密鑰管理服務(wù) HMAC C、C++
HMAC是密鑰相關(guān)的哈希運(yùn)算消息認(rèn)證碼(Hash-based Message Authentication Code),是一種基于Hash函數(shù)和密鑰進(jìn)行消息認(rèn)證的方法。
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 密鑰刪除C C++
為保證數(shù)據(jù)安全性,當(dāng)不需要使用該密鑰時(shí),應(yīng)該刪除密鑰。
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 查詢密鑰是否存在C、C++
HUKS提供了接口供應(yīng)用查詢指定密鑰是否存在。
鴻蒙開發(fā):Universal Keystore Kit密鑰管理服務(wù) 查詢密鑰是否存在C C++
HUKS提供了接口供應(yīng)用查詢指定密鑰是否存在。
鴻蒙開發(fā):Universal Keystore Kit 密鑰管理服務(wù) 獲取密鑰屬性ArkTS
HUKS提供了接口供業(yè)務(wù)獲取指定密鑰的相關(guān)屬性。在獲取指定密鑰屬性前,需要確保已在HUKS中生成或導(dǎo)入持久化存儲(chǔ)的密鑰。
鴻蒙開發(fā):Universal Keystore Kit 密鑰管理服務(wù) 獲取密鑰屬性C C++
HUKS提供了接口供業(yè)務(wù)獲取指定密鑰的相關(guān)屬性。在獲取指定密鑰屬性前,需要確保已在HUKS中生成或導(dǎo)入持久化存儲(chǔ)的密鑰。
鴻蒙開發(fā):Universal Keystore Kit 密鑰管理服務(wù) 密鑰導(dǎo)出 C C++
業(yè)務(wù)需要獲取持久化存儲(chǔ)的非對(duì)稱密鑰的公鑰時(shí)使用,當(dāng)前支持ECC/RSA/ED25519/X25519的公鑰導(dǎo)出。
評(píng)論