鸿蒙开发:Universal Keystore Kit(密钥管理服务)【加密导入密钥(C/C++)】

news/2024/12/22 11:19:24/

加密导入密钥(C/C++)

以加密导入ECDH密钥对为例,涉及业务侧加密密钥的[密钥生成]、[协商]等操作不在本示例中体现。

具体的场景介绍及支持的算法规格。

在CMake脚本中链接相关动态库

   target_link_libraries(entry PUBLIC libhuks_ndk.z.so)

开发步骤

  1. 设备A(导入设备)将待导入密钥转换成[HUKS密钥材料格式]To_Import_Key(仅针对非对称密钥,若待导入密钥是对称密钥则可省略此步骤)。
  2. 设备B(被导入设备)生成一个加密导入用途的、用于协商的非对称密钥对Wrapping_Key(公钥Wrapping_Pk,私钥Wrapping_Sk),其密钥用途设置为unwrap,导出Wrapping_Key的公钥材料Wrapping_Pk并保存。
  3. 设备A使用和设备B同样的算法,生成一个加密导入用途的、用于协商的非对称密钥对Caller_Key(公钥Caller_Pk,私钥Caller_Sk),导出Caller_Key的公钥材料Caller_Pk并保存。
  4. 设备A生成一个对称密钥Caller_Kek,该密钥后续将用于加密To_Import_Key。
  5. 设备A基于Caller_Key的私钥Caller_Sk和设备B Wrapping_Key的公钥Wrapping_Pk,协商出Shared_Key。
  6. 设备A使用Caller_Kek加密To_Import_Key,生成To_Import_Key_Enc。
  7. 设备A使用Shared_Key加密Caller_Kek,生成Caller_Kek_Enc。
  8. 设备A封装Caller_Pk、Caller_Kek_Enc、To_Import_Key_Enc等加密导入的密钥材料并发送给设备B,加密导入密钥材料格式见[加密导入密钥材料格式]。
  9. 设备B导入封装的加密密钥材料。
  10. 设备A、B删除用于加密导入的密钥。
  11. 开发前请熟悉鸿蒙开发指导文档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 realstruct 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"; // 此处仅为测试数据,实际使用时该值每次应该不同
static const uint32_t WRAPPED_KEY_IV_SIZE = 16;
static uint8_t WRAPPED_KEY_IV[IV_SIZE] = "bababababababab"; // 此处仅为测试数据,实际使用时该值每次应该不同
static const uint32_t AAD_SIZE = 16;
static uint8_t AAD[AAD_SIZE] = "abababababababa"; // 此处仅为测试数据,实际使用时该值每次应该不同
static const uint32_t NONCE_SIZE = 12;
static uint8_t NONCE[NONCE_SIZE] = "hahahahahah"; // 此处仅为测试数据,实际使用时该值每次应该不同
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}}, // 此处仅为测试数据,实际使用时该值应与调用者信息相关{.tag = OH_HUKS_TAG_NONCE,.blob = {.size = NONCE_SIZE, .data = (uint8_t *)NONCE}}}; // 此处仅为测试数据,实际使用时该值每次应该不同
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}}}; // 此处仅为测试数据,实际使用时该值每次应该不同
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}}, // 此处仅为测试数据,实际使用时该值应与调用者信息相关{.tag = OH_HUKS_TAG_NONCE,.blob = {.size = NONCE_SIZE, .data = (uint8_t *)NONCE}}}; // 此处仅为测试数据,实际使用时该值每次应该不同
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}}}; // 此处仅为测试数据,实际使用时该值每次应该不同
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;/* 计算大小 */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;/* 拷贝数据 */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 *)&params->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};/* 模拟加密导入密钥场景,设备A为远端设备(导入设备),设备B为本端设备(被导入设备) */do {/*** 1.设备A将待导入密钥转换成HUKS密钥材料格式To_Import_Key(仅针对非对称密钥,若待导入密钥是对称密钥则可省略此步骤),*   本示例使用g_importedAes256PlainKey(对称密钥)作为模拟*//* 2.设备B生成一个加密导入用途的、用于协商的非对称密钥对Wrapping_Key(公钥Wrapping_Pk,私钥Wrapping_Sk),其密钥用途设置为unwrap,导出Wrapping_Key公钥Wrapping_Pk存放在变量huksPublicKey中*/ret = GenerateAndExportHuksPublicKey(params, &huksPublicKey);if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {break;}/* 3.设备A使用和设备B同样的算法,生成一个加密导入用途的、用于协商的非对称密钥对Caller_Key(公钥Caller_Pk,私钥Caller_Sk),导出Caller_Key公钥Caller_Pk存放在变量callerSelfPublicKey中*/ret = GenerateAndExportCallerPublicKey(params, &callerSelfPublicKey);if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {break;}/*** 4. 设备A生成一个对称密钥Caller_Kek,该密钥后续将用于加密To_Import_Key* 5. 设备A基于Caller_Key的私钥Caller_Sk和设备B Wrapping_Key的公钥Wrapping_Pk,协商出Shared_Key*/ret = ImportKekAndAgreeSharedSecret(params, &huksPublicKey, &outSharedKey);if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {break;}/*** 6. 设备A使用Caller_Kek加密To_Import_Key,生成To_Import_Key_Enc* 7. 设备A使用Shared_Key加密Caller_Kek,生成Caller_Kek_Enc*/ret = EncryptImportedPlainKeyAndKek(params, &plainCipherText, &kekCipherText);if (ret.errorCode != (int32_t)OH_HUKS_SUCCESS) {break;}/* 8. 设备A封装Caller_Pk、To_Import_Key_Enc、Caller_Kek_Enc等加密导入的材料并发送给设备B。* 本示例作为变量存放在callerSelfPublicKey,plainCipherText,kekCipherText* 9. 设备B导入封装的加密密钥材料*/ret = ImportWrappedKey(params, &plainCipherText, &kekCipherText, &callerSelfPublicKey, &wrappedKeyData);} while (0);/* 10. 设备A、B删除用于加密导入的密钥 */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直接拿`

QQ截图20240705211300.png

调测验证

调用[OH_Huks_IsKeyItemExist]验证密钥是否存在,如密钥存在即表示密钥导入成功。

#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.调用OH_Huks_IsKeyItemExist判断密钥是否存在  */struct OH_Huks_Result ohResult = OH_Huks_IsKeyItemExist(&keyAlias, NULL);if (ohResult.errorCode != OH_HUKS_SUCCESS) {// 失败 } else {// 成功}
}

http://www.ppmy.cn/news/1474150.html

相关文章

C# AOP面向切面编程

AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&#xff09;是一种编程范式&#xff0c;旨在将横切关注点&#xff08;Cross-cutting Concerns&#xff09;从业务逻辑中分离出来。在传统的面向对象编程中&#xff0c;横切关注点&#xff08;如日志记录、…

elasticsearch-users和elasticsearch-reset-password介绍

elasticsearch 内置 elastic, kibana, logstash_system,beats_system 共4个用户&#xff0c;用途如下&#xff1a; elastic 账号&#xff1a;内置的超级用户&#xff0c;拥有 superuser 角色。 kibana 账号&#xff1a;用来连接 elasticsearch 并与之通信。Kibana 服务器以该用…

在网站存在漏洞的情况下强化安全防御

一、引言 网络安全是一个持续的战斗&#xff0c;尤其是在网站存在已知或未知漏洞的情况下。本文将探讨如何在网站存在漏洞的情况下&#xff0c;采取有效措施进行安全防御。 二、理解漏洞 首先&#xff0c;我们需要理解网站的漏洞。这些可能包括SQL注入、跨站脚本&#xff08…

Docker 容器出现 IP 冲突

Docker 容器出现 IP 冲突的情况可能由以下几个原因导致&#xff1a; 静态 IP 分配&#xff1a;如果你在 docker-compose.yml 文件中为多个容器手动设置了相同的静态 IP 地址&#xff0c;那么这些容器在启动时就会出现 IP 冲突。确保每个容器分配的静态 IP 地址是唯一的。桥接网…

触摸屏虚拟键盘组件 jQuery Virtual Keyboard使用 自定义键盘

如何在触摸设备上为输入域添加虚拟键盘&#xff1f; 一个插件可以解决这个问题&#xff0c;关键还支持高度自定义&#xff08;git地址&#xff09;&#xff1a; GitHub - Mottie/Keyboard: Virtual Keyboard using jQuery ~ 官网地址&#xff1a;Virtual Keyboard 使用步骤&…

快团团开团大团长和帮卖团长如何合并“收件人信息相同的订单”核销打印?

快团团开团大团长和帮卖团长如何合并“收件人信息相同的订单”核销打印&#xff1f; 一、背景 经营方式为线下自提等无需快递的团长&#xff0c;在核销打印订单时&#xff0c;需要将“收件人信息相同的订单”合并核销打印 二、操作说明 第一步&#xff0c;团长电脑端登陆快…

对标GPT-4o!不锁区、支持手机、免费使用,Moshi来啦!

7月4日凌晨&#xff0c;法国知名开源AI研究实验室Kyutai在官网发布了&#xff0c;具备看、听、说多模态大模型——Moshi。 Moshi功能与OpenAI在5月14日展示的最新模型GPT-4o差不多&#xff0c;可以听取人的语音提问后进行实时推理回答内容。但GPT-4o的语音模式要在秋天才能全面…

快递柜也上网?你身边的物联网应用

快递柜相信大家都不陌生&#xff0c;如今在各类家庭小区、写字楼、工业园区&#xff0c;各类快递柜已经融入大家的日常&#xff0c;为大家的生活带来便利。大家已经习惯指尖交互就能一键取件&#xff0c;这么便捷的体验背后其实是有一套系统运作机制在支撑的&#xff0c;今天和…