鸿蒙开发: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 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"; // 此处仅为测试数据,实际使用时该值每次应该不同
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 {
        // 成功
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/783560.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】——决策树模型

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

PHP宝藏神器多功能投票系统源码小程序

&#x1f389;发现宝藏神器&#xff01;一键解锁“多功能投票小程序”的无限可能✨ &#x1f308; 开篇安利&#xff1a;告别繁琐&#xff0c;拥抱高效&#xff01; Hey小伙伴们&#xff0c;是不是经常为组织活动、收集意见而头疼不已&#xff1f;&#x1f92f; 今天就要给大…

迭代器模式(大话设计模式)C/C++版本

迭代器模式 C #include <iostream> #include <string> #include <vector>using namespace std;// 迭代抽象类,用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法&#xff0c;统一接口 class Iterator { public:Iterator(){};virtu…

Android约束布局的概念与属性(2)

目录 3&#xff0e;链式约束4&#xff0e;辅助线 3&#xff0e;链式约束 如果两个或以上控件通过下图的方式约束在一起&#xff0c;就可以认为是他们是一条链&#xff08;如图5为横向的链&#xff0c;纵向同理&#xff09;。 图5 链示意图 如图5所示&#xff0c;在预览图中选…

面向计算机类岗位人才需求分析研究 --基于前程无忧招聘网站的数据经验证据

1 引言 随着智能互联网的快速发展和一系列的技术变革&#xff0c;从而推动全国各行业进行政策的调整、资源的共享、产业的升级和信息的创新。结合国家的战略&#xff0c;政府明确的指出&#xff0c;建设国家大数据池意义重大。通过海量数据的支持与算法优化后的计算能力&#…

水果商城系统 SpringBoot+Vue

1、技术栈 技术栈&#xff1a;SpringBootVueMybatis等使用环境&#xff1a;Windows10 谷歌浏览器开发环境&#xff1a;jdk1.8 Maven mysql Idea 数据库仅供学习参考 【已经答辩过的毕业设计】 项目源码地址 2、功能划分 3、效果演示

Perforce发布白皮书,解读电动汽车初创公司如何加速进入市场并降低软件开发中的风险和成本

电动汽车&#xff08;EV&#xff09;领域的初创企业正迅速崛起&#xff0c;创新速度显著加快。然而&#xff0c;随着消费者对电动汽车需求的激增&#xff0c;老牌汽车制造商正加速进军这一市场&#xff0c;加剧了行业竞争。为在竞争中生存并发展&#xff0c;电动汽车初创企业必…

机器学习与模式识别_清华大学出版社

contents 前言第1章 绪论1.1 引言1.2 基本术语1.3 假设空间1.4 归纳偏好1.5 发展历程1.6 应用现状 第2章 模型评估与选择2.1 经验误差与过拟合2.2 评估方法2.3 性能度量2.3.1 回归任务2.3.2 分类任务 2.4 比较检验2.5 偏差与方差2.5.1 偏差-方差分解2.5.2 偏差-方差窘境 第3章 …

新技术引领商业智能新时代:从 AI 到自助分析的演变

最新技术资源&#xff1a; https://www.grapecity.com.cn/resources/ 引言&#xff1a;商业智能的新技术浪潮 在当今数据驱动的世界中&#xff0c;技术进步不断改变着商业智能&#xff08;BI&#xff09;领域。特别是人工智能&#xff08;AI&#xff09;和自助分析工具的发展&…

python 10个自动化脚本

目录 &#x1f31f; 引言 &#x1f4da; 理论基础 &#x1f6e0;️ 使用场景与代码示例 场景一&#xff1a;批量重命名文件 场景二&#xff1a;自动下载网页内容 场景三&#xff1a;数据清洗 场景四&#xff1a;定时执行任务 场景五&#xff1a;自动化邮件发送 场景六…

10分钟使用网站构建框架hugo本地搭建个人网站并快速上线详细教程

文章目录 前言1. 安装环境2. 配置环境变量与hugo安装2.1 创建程序目录2.2 配置环境变量2.3 查看程序版本 3. 创建博客网站3.1 创建站点3.2 在站点中创建一篇文章3.3 为网站添加主题 4. 本地访问测试5. 安装内网穿透工具6. 配置公网地址7. 配置固定公网地址 前言 今天和大家分享…

压测引擎数据库设计(上)

压测引擎数据库设计&#xff08;上&#xff09; 引言 在当今快速发展的互联网时代&#xff0c;软件质量保证和性能测试变得尤为重要。自动化测试平台&#xff0c;提供了一套完整的解决方案&#xff0c;以确保软件产品在发布前能够满足性能和稳定性的要求。本文将深入探讨滴云自…

启发式防御大模型越狱攻击

前言 在本文中&#xff0c;我们来分析、复现几个典型的启发式的防御工作&#xff0c;用于防御面向大语言模型的越狱攻击。 Self Examination 首先来看Self Examination方法。 这是一种简单的零样本防御LLM攻击的方法&#xff0c;旨在防止用户接触到由LLMs诱导产生的有害或恶…

ROS编译错误: fatal error: test_pkg/test_pkg.h: 没有那个文件

在ROS安装完毕后编译ros工作空间&#xff0c;出现了以下错误: 解决方法: 删除工作空间&#xff0c;重建再重新编译

【数据结构】单链表:数据结构中的舞者,穿梭于理论与实践的舞池

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 数据结构与算法 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 一、链表的概念和结构 1.1 链表的概念 在上一篇文章中&#xff0c;我们了解了线性表(linear list)&#xff0c;并且学习了其…

你认为最优美的数据结构是什么?

并查集算是&#xff0c;巧妙的不行&#xff0c;让人为之一惊。 在学习数据结构Q的时候&#xff0c;老师多少会提到并查集&#xff0c;他的应用也是超级广泛。本文首先会通过案例来对并查集有一个介绍。然后给出并查集的java实现。 刚好我有一些资料&#xff0c;是我根据网友给…

【Altium】AD-网络版一个用户非人为异常占用多个License的解决方法

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 当出现一个用户同时占用多个授权&#xff0c;又无法单独释放一个授权的情况下&#xff0c;该如何解决。 2、 问题场景 一个用户获取网络版授权后&#xff0c;AD会自动重复获取授权&#xff0c;直到该license下所有授…

怎么给电子文档批量盖骑缝章或公章?

怎么给电子文档批量盖骑缝章或公章?假如你有100个PDF电子文档要同时盖缝章&#xff0c;如果不借助专业的盖电子骑缝章软件&#xff0c;还真不好干。下面讲述如何利用e-章宝批量盖电子骑缝章。 1.在软件中导入待批量盖章的PDF文件 如下图&#xff0c;在“待盖章PDF文件”区域…

后端之路——登录校验

前言&#xff1a;Servlet 【登录校验】这个功能技术的基础是【会话技术】&#xff0c;那么在讲【会话技术】的时候必然要谈到【Cookie】和【Session】这两个东西&#xff0c;那么在这之前必须要先讲一下一个很重要但是很多人都会忽略的一个知识点&#xff1a;【Servlet】 什么是…

redis-cli 连接Redis

Redis-cli介绍 redis-cli 是原生 Redis 自带的命令行工具&#xff0c;您可以在云主机或本地设备上通过 redis-cli 连接 Redis 数据库&#xff0c;进行数据管理。 redis-cli 客户端的使用方法&#xff0c;请参考官方文档。 连接命令 redis-cli -h <redis_instance_address…