鸿蒙开发: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,一经查实,立即删除!

相关文章

【NLP学习路线的总结】

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

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;专门的除臭技术能有…

写一个函数,返回参数二进制中 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…

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

在选择电脑类型时&#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…

电子版盖章怎么弄(电子版公章怎么盖上)

下面是利用e章宝盖电子公章更简单&#xff0c;从印章库中选中要盖的公章&#xff0c;然后在文档中想要盖的位置单击一下即可&#xff1a; 第一步&#xff1a;制作需要盖的电子印章 一般是先扫描公章&#xff0c;然后使用e章宝的一键抠章功能&#xff0c;把印章导入到印章库中…

音频demo:使用fdk-aac将PCM数据编码成aac数据

1、README a. 编译 编译demo 本demo是使用的开源项目fdk-aac将PCM数据编码成aac音频文件。由于提供的.a静态库是在x86_64的机器上编译的&#xff0c;所以默认情况下仅支持该架构的主机上编译运行。 $ make编译fdk-aac&#xff08;可选&#xff09; 如果想要在其他架构的CP…

Java语言程序设计——篇二(1)

Java语言基础 数据类型关键字与标识符关键字标识符 常量与变量1、常量2、变量 类型转换自动类型转换强制类型转换 数据类型 数据的基本要素数据的性质&#xff08;数据结构&#xff09;数据的取值范围&#xff08;字节大小&#xff09;数据的存储方式参与的运算 Java是一门强类…

常见的自动化工具开发必备的源代码!

随着科技的飞速发展&#xff0c;自动化工具已经成为我们日常工作中不可或缺的一部分&#xff0c;自动化工具不仅极大地提高了工作效率&#xff0c;还降低了人为错误的可能性。 然而&#xff0c;要想开发出高效、稳定的自动化工具&#xff0c;掌握一些常见的源代码技巧是至关重…

vue中一周的时间选择多个阶段(手动表格选择)

先给大家看一下效果图 源代码 <template><div style"width: 45%"><div style"width: 100%"><div class"time"><div class"timeleft">星期/时间</div><div class"timeright"><…

FastAPI是一个现代、快速(高性能)的Web框架

FastAPI是一个现代、快速&#xff08;高性能&#xff09;的Web框架&#xff0c;专门用于构建基于Python的API。以下是对FastAPI的详细介绍&#xff1a; 一、基本概述 定义与用途&#xff1a;FastAPI是一个开源项目&#xff0c;基于Starlette和Pydantic库构建而成&#xff0c;…

奇安信20240513笔试

题目一 解题思路 n转为字符串&#xff0c;如果位数为偶数&#xff0c;取前一半设为x&#xff0c;后一段为y&#xff0c;从x最低位开始&#xff0c;9&#xff0c;9*10&#xff0c;9*10*10。。。 到最高位&#xff0c;加x&#xff0c;如果x大于或等于y&#xff0c;加1. 位数为奇数…

linux固定主机ip

1.查看虚拟网络配置 NAT设置&#xff1a; 2.修改网卡配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"static" DEFROUTE"yes" IPV4_FAILURE_FATAL…