1e41f4b71Sopenharmony_ci# HMAC(C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciHMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code),是一种基于Hash函数和密钥进行消息认证的方法。
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci## 在CMake脚本中链接相关动态库
7e41f4b71Sopenharmony_ci```txt
8e41f4b71Sopenharmony_ci   target_link_libraries(entry PUBLIC libhuks_ndk.z.so)
9e41f4b71Sopenharmony_ci```
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci## 开发步骤
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci**生成密钥**
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci1. 指定密钥别名。
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci2. 初始化密钥属性集。
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci3. 调用OH_Huks_GenerateKeyItem生成密钥,HMAC支持的规格请参考[密钥生成](huks-key-generation-overview.md#支持的算法)。
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci除此之外,开发者也可以参考[密钥导入](huks-key-import-overview.md#支持的算法)的规格介绍,导入已有的密钥。
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci**执行HMAC**
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci1. 获取密钥别名。
26e41f4b71Sopenharmony_ci
27e41f4b71Sopenharmony_ci2. 获取待运算的数据。
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci3. 调用[OH_Huks_InitParamSet](../../reference/apis-universal-keystore-kit/_huks_param_set_api.md#oh_huks_initparamset)指定算法参数配置。
30e41f4b71Sopenharmony_ci   
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci4. 调用[OH_Huks_InitSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_initsession)初始化密钥会话,并获取会话的句柄handle。
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci5. 调用[OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_finishsession)结束密钥会话,获取哈希后的数据。
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci```c++
37e41f4b71Sopenharmony_ci#include "huks/native_huks_api.h"
38e41f4b71Sopenharmony_ci#include "huks/native_huks_param.h"
39e41f4b71Sopenharmony_ci#include <string.h>
40e41f4b71Sopenharmony_ciOH_Huks_Result InitParamSet(
41e41f4b71Sopenharmony_ci    struct OH_Huks_ParamSet **paramSet,
42e41f4b71Sopenharmony_ci    const struct OH_Huks_Param *params,
43e41f4b71Sopenharmony_ci    uint32_t paramCount)
44e41f4b71Sopenharmony_ci{
45e41f4b71Sopenharmony_ci    OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet);
46e41f4b71Sopenharmony_ci    if (ret.errorCode != OH_HUKS_SUCCESS) {
47e41f4b71Sopenharmony_ci        return ret;
48e41f4b71Sopenharmony_ci    }
49e41f4b71Sopenharmony_ci    ret = OH_Huks_AddParams(*paramSet, params, paramCount);
50e41f4b71Sopenharmony_ci    if (ret.errorCode != OH_HUKS_SUCCESS) {
51e41f4b71Sopenharmony_ci        OH_Huks_FreeParamSet(paramSet);
52e41f4b71Sopenharmony_ci        return ret;
53e41f4b71Sopenharmony_ci    }
54e41f4b71Sopenharmony_ci    ret = OH_Huks_BuildParamSet(paramSet);
55e41f4b71Sopenharmony_ci    if (ret.errorCode != OH_HUKS_SUCCESS) {
56e41f4b71Sopenharmony_ci        OH_Huks_FreeParamSet(paramSet);
57e41f4b71Sopenharmony_ci        return ret;
58e41f4b71Sopenharmony_ci    }
59e41f4b71Sopenharmony_ci    return ret;
60e41f4b71Sopenharmony_ci}
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_cistatic struct OH_Huks_Param g_genHmacParams[] = {
63e41f4b71Sopenharmony_ci    {
64e41f4b71Sopenharmony_ci        .tag = OH_HUKS_TAG_ALGORITHM,
65e41f4b71Sopenharmony_ci        .uint32Param = OH_HUKS_ALG_HMAC
66e41f4b71Sopenharmony_ci    }, {
67e41f4b71Sopenharmony_ci        .tag = OH_HUKS_TAG_PURPOSE,
68e41f4b71Sopenharmony_ci        .uint32Param = OH_HUKS_KEY_PURPOSE_MAC
69e41f4b71Sopenharmony_ci    }, {
70e41f4b71Sopenharmony_ci        .tag = OH_HUKS_TAG_KEY_SIZE,
71e41f4b71Sopenharmony_ci        .uint32Param = OH_HUKS_AES_KEY_SIZE_256
72e41f4b71Sopenharmony_ci    }, {
73e41f4b71Sopenharmony_ci        .tag = OH_HUKS_TAG_DIGEST,
74e41f4b71Sopenharmony_ci        .uint32Param = OH_HUKS_DIGEST_SHA384
75e41f4b71Sopenharmony_ci    }
76e41f4b71Sopenharmony_ci};
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_cistatic const uint32_t HMAC_COMMON_SIZE = 1024;
79e41f4b71Sopenharmony_ciOH_Huks_Result HksHmacTest(
80e41f4b71Sopenharmony_ci        const struct OH_Huks_Blob *keyAlias,
81e41f4b71Sopenharmony_ci        const struct OH_Huks_ParamSet *hmacParamSet, const struct OH_Huks_Blob *inData, struct OH_Huks_Blob *hashText)
82e41f4b71Sopenharmony_ci{
83e41f4b71Sopenharmony_ci    uint8_t handleE[sizeof(uint64_t)] = {0};
84e41f4b71Sopenharmony_ci    struct OH_Huks_Blob handle = {sizeof(uint64_t), handleE};
85e41f4b71Sopenharmony_ci    OH_Huks_Result ret = OH_Huks_InitSession(keyAlias, hmacParamSet, &handle, nullptr);
86e41f4b71Sopenharmony_ci    if (ret.errorCode != OH_HUKS_SUCCESS) {
87e41f4b71Sopenharmony_ci        return ret;
88e41f4b71Sopenharmony_ci    }
89e41f4b71Sopenharmony_ci    ret = OH_Huks_FinishSession(&handle, hmacParamSet, inData, hashText);
90e41f4b71Sopenharmony_ci    return ret;
91e41f4b71Sopenharmony_ci}
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_cistatic napi_value HmacKey(napi_env env, napi_callback_info info)
94e41f4b71Sopenharmony_ci{
95e41f4b71Sopenharmony_ci    char tmpKeyAlias[] = "test_hmac";
96e41f4b71Sopenharmony_ci    struct OH_Huks_Blob keyAlias = { (uint32_t)strlen(tmpKeyAlias), (uint8_t *)tmpKeyAlias };
97e41f4b71Sopenharmony_ci    struct OH_Huks_ParamSet *hmacParamSet = nullptr;
98e41f4b71Sopenharmony_ci    OH_Huks_Result ohResult;
99e41f4b71Sopenharmony_ci    do {
100e41f4b71Sopenharmony_ci        /* 1. Generate Key */
101e41f4b71Sopenharmony_ci        /*
102e41f4b71Sopenharmony_ci        * 模拟生成密钥场景
103e41f4b71Sopenharmony_ci        * 1.1. 确定密钥别名
104e41f4b71Sopenharmony_ci        */
105e41f4b71Sopenharmony_ci        /*
106e41f4b71Sopenharmony_ci        * 1.2. 获取生成密钥算法参数配置
107e41f4b71Sopenharmony_ci        */
108e41f4b71Sopenharmony_ci        ohResult = InitParamSet(&hmacParamSet, g_genHmacParams, sizeof(g_genHmacParams) / sizeof(OH_Huks_Param));
109e41f4b71Sopenharmony_ci        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
110e41f4b71Sopenharmony_ci            break;
111e41f4b71Sopenharmony_ci        }
112e41f4b71Sopenharmony_ci        /*
113e41f4b71Sopenharmony_ci        * 1.3. 调用generateKeyItem
114e41f4b71Sopenharmony_ci        */
115e41f4b71Sopenharmony_ci        ohResult = OH_Huks_GenerateKeyItem(&keyAlias, hmacParamSet, nullptr);
116e41f4b71Sopenharmony_ci        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
117e41f4b71Sopenharmony_ci            break;
118e41f4b71Sopenharmony_ci        }
119e41f4b71Sopenharmony_ci        /* 2. Hmac */
120e41f4b71Sopenharmony_ci        /*
121e41f4b71Sopenharmony_ci        * 模拟哈希场景
122e41f4b71Sopenharmony_ci        * 2.1. 获取密钥别名
123e41f4b71Sopenharmony_ci        */
124e41f4b71Sopenharmony_ci        /*
125e41f4b71Sopenharmony_ci        * 2.2. 获取待哈希的数据
126e41f4b71Sopenharmony_ci        */
127e41f4b71Sopenharmony_ci        char tmpInData[] = "HMAC_MAC_INDATA_1";
128e41f4b71Sopenharmony_ci        struct OH_Huks_Blob inData = { (uint32_t)strlen(tmpInData), (uint8_t *)tmpInData };
129e41f4b71Sopenharmony_ci        uint8_t cipher[HMAC_COMMON_SIZE] = {0};
130e41f4b71Sopenharmony_ci        struct OH_Huks_Blob hashText = {HMAC_COMMON_SIZE, cipher};
131e41f4b71Sopenharmony_ci        /*
132e41f4b71Sopenharmony_ci        * 2.3. 调用initSession获取handle
133e41f4b71Sopenharmony_ci        */
134e41f4b71Sopenharmony_ci        /*
135e41f4b71Sopenharmony_ci        * 2.4. 调用finishSession获取哈希后的内容
136e41f4b71Sopenharmony_ci        */
137e41f4b71Sopenharmony_ci        ohResult = HksHmacTest(&keyAlias, hmacParamSet, &inData, &hashText);
138e41f4b71Sopenharmony_ci        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
139e41f4b71Sopenharmony_ci            break;
140e41f4b71Sopenharmony_ci        }
141e41f4b71Sopenharmony_ci    } while (0);
142e41f4b71Sopenharmony_ci    OH_Huks_FreeParamSet(&hmacParamSet);
143e41f4b71Sopenharmony_ci}
144e41f4b71Sopenharmony_ci```
145