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

从API 20开始，支持加密导出导入密钥。

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

target\_link\_libraries(entry PUBLIC libhuks\_ndk.z.so)

#### 开发步骤

1.  初始化生成密钥属性集，需要设置[OH\_HUKS\_TAG\_IS\_ALLOWED\_WRAP](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-type-h#oh_huks_tag)，指定密钥允许导出。
    
2.  调用[OH\_Huks\_GenerateKeyItem](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-api-h#oh_huks_generatekeyitem)生成密钥，具体请参考[密钥生成](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-generation-overview)。
    
3.  调用[OH\_Huks\_WrapKey](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-api-h#oh_huks_wrapkey)加密导出密钥。
    
4.  调用[OH\_Huks\_UnwrapKey](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-api-h#oh_huks_unwrapkey)加密导入密钥。
    

#### 开发案例

#include "huks/native\_huks\_api.h"
#include "huks/native\_huks\_param.h"
#include "napi/native\_api.h"
#include <string.h>

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 OH\_Huks\_Param g\_testGenerateKeyParam\[\] = {
    {
        .tag = OH\_HUKS\_TAG\_ALGORITHM,
        .uint32Param = OH\_HUKS\_ALG\_ECC
    }, {
        .tag = OH\_HUKS\_TAG\_PURPOSE,
        .uint32Param = OH\_HUKS\_KEY\_PURPOSE\_AGREE
    }, {
        .tag = OH\_HUKS\_TAG\_KEY\_SIZE,
        .uint32Param = OH\_HUKS\_ECC\_KEY\_SIZE\_256
    }, {
        .tag = OH\_HUKS\_TAG\_DIGEST,
        .uint32Param = OH\_HUKS\_DIGEST\_NONE
    }, {
        .tag = OH\_HUKS\_TAG\_IS\_ALLOWED\_WRAP,
        .boolParam = true
    }
};

struct OH\_Huks\_Param g\_wrapKeyParam\[\] = {
    {
        .tag = OH\_HUKS\_TAG\_KEY\_WRAP\_TYPE,
        .uint32Param = OH\_HUKS\_KEY\_WRAP\_TYPE\_HUK\_BASED
    }
};

static napi\_value GenerateKey(napi\_env env, napi\_callback\_info info)
{
    /\* 1.确定密钥别名 \*/
    const char \*alias = "test\_generate";
    struct OH\_Huks\_Blob aliasBlob = { .size = (uint32\_t)strlen(alias), .data = (uint8\_t \*)alias };
    struct OH\_Huks\_ParamSet \*testGenerateKeyParamSet = nullptr;
    struct OH\_Huks\_ParamSet \*wrapKeyParamSet = nullptr;
    struct OH\_Huks\_Result ohResult;
    do {
        /\* 2.初始化密钥属性集 \*/
        ohResult = InitParamSet(&testGenerateKeyParamSet, g\_testGenerateKeyParam,
            sizeof(g\_testGenerateKeyParam) / sizeof(OH\_Huks\_Param));
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
        
        /\* 3.生成密钥 \*/
        ohResult = OH\_Huks\_GenerateKeyItem(&aliasBlob, testGenerateKeyParamSet, nullptr);
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
        
        /\* 4.初始化加密导出导入密钥属性集 \*/
        ohResult = InitParamSet(&wrapKeyParamSet, g\_wrapKeyParam,
            sizeof(g\_wrapKeyParam) / sizeof(OH\_Huks\_Param));
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
        
        /\* 5.加密导出密钥 \*/
        uint8\_t WrappedData\[2048\] = {0};
        struct OH\_Huks\_Blob wrappedKey = {2048, WrappedData};
        ohResult = OH\_Huks\_WrapKey(&aliasBlob, wrapKeyParamSet, &wrappedKey);
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
        
        /\* 6.加密导入密钥 \*/
        ohResult = OH\_Huks\_UnwrapKey(&aliasBlob, wrapKeyParamSet, &wrappedKey);
    } while (0);
    OH\_Huks\_FreeParamSet(&testGenerateKeyParamSet);
    OH\_Huks\_FreeParamSet(&wrapKeyParamSet);
    napi\_value ret;
    napi\_create\_int32(env, ohResult.errorCode, &ret);
    return ret;
}