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

加密导入密钥(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.mzph.cn/pingmian/43014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模电基础 - 集成运算放大电路

目录 一. 简介 二. 直接耦合放大电路 三. 阻容耦合放大电路 四. 变压器耦合放大电路 五. 光电耦合 六. 集成运放电路 1. 双集成运放电路 2.单集成运放电路 3.单集和双集混合 一. 简介 集成运算放大电路简称集成运放&#xff0c;是一种具有高增益、高输入电阻和低输出电…

SpringBoot 定时任务之@Scheduled cron表达式

在Spring Boot中&#xff0c;Scheduled注解配合Cron表达式可以用来定义定时任务。 Cron表达式是一种灵活的时间表达方式&#xff0c;通常用于配置任务的执行周期。 以下是一些关键点和示例&#xff1a; 1. 开启定时任务支持 要在Spring Boot应用中使用定时任务&#xff0c;首…

【NLP学习路线的总结】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 目录 0. 👉前言1. 👉前置知识👉基础数学知识👉编程语言👉…

代码随想录算法训练营第58天 [101.孤岛的总面积 102.沉没孤岛 103.水流问题 104.建造最大岛屿]

代码随想录算法训练营第58天 [101.孤岛的总面积 102.沉没孤岛 103.水流问题 104.建造最大岛屿] 一、101.孤岛的总面积 链接: 代码随想录. 思路&#xff1a;从四个边缘开始深搜&#xff0c;搜到了标记为2&#xff0c;这样所有为2和0的就不是孤岛&#xff0c;所有为1的就是孤岛 做…

记录一次ffmpeg手动编译出现的问题

前言部分 使用环境: ubuntu 22.04 最近手动编译了一次的ffmpeg&#xff08;参考博客ffmpeg学习&#xff1a;ubuntu下编译ffmpeg(全网最懒的编译脚本)&#xff09;&#xff0c;但是过程出现了一些问题&#xff0c;因此在此记录一下&#xff0c;若有疑问&#xff0c;欢迎讨论~。 …

MHA Master High Availability

一、MHA工作原理和架构 MHA利用 SELECT 1 As Value 指令判断master服务器的健康性,一旦master 宕机,MHA 从宕机崩溃的master保存二进制日志事件&#xff08;binlog events&#xff09;识别含有最新更新的slave应用差异的中继日志&#xff08;relay log&#xff09;到其他的sla…

centos 7.9安装subversion

一、安装subversion yum install -y subversion

20240709 每日AI必读资讯

&#x1f9e0;手把手教你如何打造《星际穿越》中的 TARS 机器人复制品&#xff01; - 一位名为 Charles Diaz 的开发者使用树莓派创建了一个完全功能的 TARS 复制品。 - 使用树莓派3B作为主控&#xff0c;配合Adafruit PCA-9685伺服驱动器&#xff0c;通过编写的步态控制程序…

C++ lambda按引用捕获导致的空悬指针问题

lambda可以按值捕获&#xff0c;也可以按引用捕获。按引用捕获会导致闭包包含指涉到局部变量的引用&#xff0c;或者指涉到定义lambda式的作用域内形参的引用。一旦lambda式所创建的闭包越过了该局部变量或者形参的生命周期&#xff0c;那么闭包内的引用就会空悬。比如下面这段…

给您介绍工控CAN总线

CAN是什么 CAN&#xff0c;全称Controller Area Network&#xff0c;即控制器局域网&#xff0c;是一种由Bosch公司在1983年开发的通信协议。它主要用于汽车和工业环境中的电子设备之间的通信。CAN协议定义了物理层和数据链路层的通信机制&#xff0c;使得不同的设备能够通过CA…

家里猫咪浮毛太多怎么办?值得买的猫毛空气净化器推荐

作为一位拥有5年铲屎经验的铲屎官&#xff0c;我知道许多新手铲屎官可能听说过宠物空气净化器&#xff0c;但了解得不多。事实上&#xff0c;宠物空气净化器确实是养猫家庭必备的小家电之一。它的大面积进风口可以有效吸附空气中的微小浮毛和皮屑&#xff0c;专门的除臭技术能有…

Typescript【网址取ID传入后端API】

网址取ID传入后端API 实现部分typescript&#xff08;前端&#xff09; 实现部分 <a href{zyjs?id5} key{5} className“o_on”>动漫建模 typescript&#xff08;前端&#xff09; 第一部分&#xff1a;获取查询字符串 如果URL是https://**/zyjs?id5&#xff0c;那么…

写一个函数,返回参数二进制中 1 的个数

代码要求 输入一个整数n&#xff0c;输出该数32位二进制中为1的个数&#xff08;包括最高位的符号位&#xff09;&#xff0c;其中负数用补码表示 如&#xff1a;输入&#xff1a;15 &#xff08;15的二进制表示&#xff1a;0000 1111&#xff09; 输出&#xff1a;4 代码实…

【server】1、后台基础搭建

1、父工程创建 1.1新建 1.2 父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"h…

Kafka 面试题精选

1. Kafka 基础知识与概念 Apache Kafka: 开源分布式事件流平台&#xff0c;用于实时数据处理与传输。主要用途: 大数据实时处理、日志聚合与传输、消息队列与微服务集成、网站活动追踪与用户行为分析、数据集成。 2. Kafka 架构与设计 Producer: 发布消息到 Kafka 集群的应用…

记一次因ThreadPoolExecutor多线程导致服务器内存压满问题

经过下载服务器内存数据得知是通过多线程业务处理查询list集合数据没有得到正确释放导致的。 首先先了解一下list集合数据的存放和回收&#xff08;可能说的不对&#xff0c;请谅解【挠头】&#xff09; 存放&#xff1a; 当我们创建一个list或者从数据库查询出的数据用list集…

电脑选购全解析!你需要知道的一切!

在选择电脑类型时&#xff0c;你可以考虑以下因素&#xff1a; 你的主要用途是什么&#xff1f; 你是否需要携带电脑&#xff1f; 你的预算是多少&#xff1f; 你对性能和图形要求有多高&#xff1f; 你是否需要特定的软硬件功能&#xff1f;根据这些因素&#xff0c;你可以…

【计算机网络】阻塞队列以及生产者消费者模型

目录 阻塞队列一. 概念二. 标准库中的阻塞队列三. 生产者消费者模型四. 阻塞队列实现 总结 阻塞队列 一. 概念 阻塞队列是⼀种特殊的队列.也遵守"先进先出"的原则. 阻塞队列能是⼀种线程安全的数据结构,并且具有以下特性: 当队列满的时候,继续⼊队列就会阻塞,直到…

Git秘籍大公开:从基础概念到高级技巧的全面解析

文章目录 前言一、Git基础介绍1. 作用2. 为什么要进行源代码管理?3. Git的诞生4. Git管理源代码特点5. Git操作流程图解 二、工作区暂存区和仓库区介绍1. 工作区2. 暂存区3. 仓库区 三、Git单人本地仓库操作1. 安装git2. 查看git安装结果3. 创建项目4. 创建本地仓库5. 配置个人…

SpringCloud 负载均衡

目录 一、负载均衡 1、问题 2、什么是负载均衡 服务端负载均衡 客户端负载均衡 二、Spring Cloud LoadBalance 1、使用 Spring Cloud LoadBalance 2、负载均衡策略 3、LoadBalancer 原理 一、负载均衡 1、问题 我们来看一下前面写的代码&#xff1a; List<Serv…