• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 密钥派生(C/C++)
2
3<!--Kit: Universal Keystore Kit-->
4<!--Subsystem: Security-->
5<!--Owner: @wutiantian-gitee-->
6<!--Designer: @HighLowWorld-->
7<!--Tester: @wxy1234564846-->
8<!--Adviser: @zengyawen-->
9
10以HKDF256密钥为例,完成密钥派生。具体的场景介绍及支持的算法规格,请参考[密钥生成支持的算法](huks-key-generation-overview.md#支持的算法)。
11
12## 在CMake脚本中链接相关动态库
13```txt
14target_link_libraries(entry PUBLIC libhuks_ndk.z.so)
15```
16
17## 开发步骤
18
19**生成密钥**
20
211. 指定密钥别名,密钥别名命名规范参考[密钥生成介绍及算法规格](huks-key-generation-overview.md)。
22
232. 初始化密钥属性集,可指定参数,OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG(可选),用于标识基于该密钥派生出的密钥是否由HUKS管理。
24
25    - 当TAG设置为OH_HUKS_STORAGE_ONLY_USED_IN_HUKS时,表示基于该密钥派生出的密钥,由HUKS管理,可保证派生密钥全生命周期不出安全环境。
26
27    - 当TAG设置为OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED时,表示基于该密钥派生出的密钥,返回给调用方管理,由业务自行保证密钥安全。
28
29    - 若业务未设置TAG的具体值,表示基于该密钥派生出的密钥,即可由HUKS管理,也可返回给调用方管理,业务可在后续派生时再选择使用何种方式保护密钥。
30
313. 调用[OH_Huks_GenerateKeyItem](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_generatekeyitem)生成密钥,具体请参考[密钥生成](huks-key-generation-overview.md)。
32
33除此之外,开发者也可以参考[密钥导入](huks-key-import-overview.md),导入已有的密钥。
34
35**密钥派生**
36
371. 获取密钥别名,指定对应的属性参数HuksOptions。
38
39   可指定参数OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG(可选),用于标识派生得到的密钥是否由HUKS管理。
40
41    | 生成 | 派生 | 规格 |
42    | -------- | -------- | -------- |
43    | OH_HUKS_STORAGE_ONLY_USED_IN_HUKS | OH_HUKS_STORAGE_ONLY_USED_IN_HUKS | 密钥由HUKS管理 |
44    | OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED | OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED | 密钥返回给调用方管理 |
45    | 未指定TAG具体值 | OH_HUKS_STORAGE_ONLY_USED_IN_HUKS | 密钥由HUKS管理 |
46    | 未指定TAG具体值 | OH_HUKS_STORAGE_KEY_EXPORT_ALLOWED | 密钥返回给调用方管理 |
47    | 未指定TAG具体值 | 未指定TAG具体值 | 密钥返回给调用方管理 |
48
49    注:派生时指定的TAG值,不可与生成时指定的TAG值冲突。表格中仅列举有效的指定方式。
50
512. 调用[OH_Huks_InitSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_initsession)初始化密钥会话,并获取会话的句柄handle。
52
533. 调用[OH_Huks_UpdateSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_updatesession)更新密钥会话。
54
554. 调用[OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/capi-native-huks-api-h.md#oh_huks_finishsession)结束密钥会话,完成派生。
56
57**删除密钥**
58
59当密钥废弃不用时,需要调用OH_Huks_DeleteKeyItem删除密钥,具体请参考[密钥删除](huks-delete-key-ndk.md)。
60
61```c++
62#include "huks/native_huks_api.h"
63#include "huks/native_huks_param.h"
64#include "napi/native_api.h"
65#include <string.h>
66OH_Huks_Result InitParamSet(
67    struct OH_Huks_ParamSet **paramSet,
68    const struct OH_Huks_Param *params,
69    uint32_t paramCount)
70{
71    OH_Huks_Result ret = OH_Huks_InitParamSet(paramSet);
72    if (ret.errorCode != OH_HUKS_SUCCESS) {
73        return ret;
74    }
75    ret = OH_Huks_AddParams(*paramSet, params, paramCount);
76    if (ret.errorCode != OH_HUKS_SUCCESS) {
77        OH_Huks_FreeParamSet(paramSet);
78        return ret;
79    }
80    ret = OH_Huks_BuildParamSet(paramSet);
81    if (ret.errorCode != OH_HUKS_SUCCESS) {
82        OH_Huks_FreeParamSet(paramSet);
83        return ret;
84    }
85    return ret;
86}
87static const uint32_t DERIVE_KEY_SIZE_32 = 32;
88static const uint32_t DERIVE_KEY_SIZE_256 = 256;
89static struct OH_Huks_Blob g_deriveKeyAlias = {
90    (uint32_t)strlen("test_derive"),
91    (uint8_t *)"test_derive"
92};
93static struct OH_Huks_Param g_genDeriveParams[] = {
94    {
95        .tag =  OH_HUKS_TAG_ALGORITHM,
96        .uint32Param = OH_HUKS_ALG_AES
97    }, {
98        .tag =  OH_HUKS_TAG_PURPOSE,
99        .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE
100    }, {
101        .tag =  OH_HUKS_TAG_DIGEST,
102        .uint32Param = OH_HUKS_DIGEST_SHA256
103    }, {
104        .tag =  OH_HUKS_TAG_KEY_SIZE,
105        .uint32Param = OH_HUKS_AES_KEY_SIZE_256
106    }
107};
108static struct OH_Huks_Param g_hkdfParams[] = {
109    {
110        .tag =  OH_HUKS_TAG_ALGORITHM,
111        .uint32Param = OH_HUKS_ALG_HKDF
112    }, {
113        .tag =  OH_HUKS_TAG_PURPOSE,
114        .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE
115    }, {
116        .tag =  OH_HUKS_TAG_DIGEST,
117        .uint32Param = OH_HUKS_DIGEST_SHA256
118    }, {
119        .tag =  OH_HUKS_TAG_DERIVE_KEY_SIZE,
120        .uint32Param = DERIVE_KEY_SIZE_32
121    }
122};
123static struct OH_Huks_Param g_hkdfFinishParams[] = {
124    {
125        .tag =  OH_HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
126        .uint32Param = OH_HUKS_STORAGE_ONLY_USED_IN_HUKS
127    }, {
128        .tag =  OH_HUKS_TAG_KEY_ALIAS,
129        .blob = g_deriveKeyAlias
130    }, {
131        .tag =  OH_HUKS_TAG_ALGORITHM,
132        .uint32Param = OH_HUKS_ALG_AES
133    }, {
134        .tag =  OH_HUKS_TAG_KEY_SIZE,
135        .uint32Param = DERIVE_KEY_SIZE_256
136    }, {
137        .tag =  OH_HUKS_TAG_PURPOSE,
138        .uint32Param = OH_HUKS_KEY_PURPOSE_DERIVE
139    }, {
140        .tag =  OH_HUKS_TAG_DIGEST,
141        .uint32Param = OH_HUKS_DIGEST_SHA256
142    }
143};
144static const uint32_t COMMON_SIZE = 2048;
145static const char *g_deriveInData = "Hks_HKDF_Derive_Test_00000000000000000000000000000000000000000000000000000000000"
146                                    "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
147                                    "0000000000000000000000000000000000000000000000000000000000000000000000000_string";
148static napi_value DeriveKey(napi_env env, napi_callback_info info)
149{
150    struct OH_Huks_Blob genAlias = {
151        (uint32_t)strlen("test_signVerify"),
152        (uint8_t *)"test_signVerify"
153    };
154    struct OH_Huks_Blob inData = {
155        (uint32_t)strlen(g_deriveInData),
156        (uint8_t *)g_deriveInData
157    };
158    struct OH_Huks_ParamSet *genParamSet = nullptr;
159    struct OH_Huks_ParamSet *hkdfParamSet = nullptr;
160    struct OH_Huks_ParamSet *hkdfFinishParamSet = nullptr;
161    OH_Huks_Result ohResult;
162    do {
163        ohResult = InitParamSet(&genParamSet, g_genDeriveParams, sizeof(g_genDeriveParams) / sizeof(OH_Huks_Param));
164        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
165            break;
166        }
167
168        ohResult = InitParamSet(&hkdfParamSet, g_hkdfParams, sizeof(g_hkdfParams) / sizeof(OH_Huks_Param));
169        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
170           break;
171        }
172
173        // finish paramset
174        ohResult = InitParamSet(&hkdfFinishParamSet, g_hkdfFinishParams,
175            sizeof(g_hkdfFinishParams) / sizeof(OH_Huks_Param));
176        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
177            break;
178        }
179
180        /* 1. Generate Key */
181        ohResult = OH_Huks_GenerateKeyItem(&genAlias, genParamSet, nullptr);
182        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
183            break;
184        }
185        /* 2. Derive */
186        // Init
187        uint8_t handleD[sizeof(uint64_t)] = {0};
188        struct OH_Huks_Blob handleDerive = { sizeof(uint64_t), handleD };
189        ohResult = OH_Huks_InitSession(&genAlias, hkdfParamSet, &handleDerive, nullptr);
190        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
191            break;
192        }
193        // Update
194        uint8_t tmpOut[COMMON_SIZE] = {0};
195        struct OH_Huks_Blob outData = { COMMON_SIZE, tmpOut };
196        ohResult = OH_Huks_UpdateSession(&handleDerive, hkdfParamSet, &inData, &outData);
197        if (ohResult.errorCode != OH_HUKS_SUCCESS) {
198            break;
199        }
200        // Finish
201        uint8_t outDataD[COMMON_SIZE] = {0};
202        struct OH_Huks_Blob outDataDerive = { COMMON_SIZE, outDataD };
203        ohResult = OH_Huks_FinishSession(&handleDerive, hkdfFinishParamSet, &inData, &outDataDerive);
204    } while (0);
205    (void)OH_Huks_DeleteKeyItem(&genAlias, nullptr);
206    (void)OH_Huks_DeleteKeyItem(&g_deriveKeyAlias, nullptr);
207    OH_Huks_FreeParamSet(&genParamSet);
208    OH_Huks_FreeParamSet(&hkdfParamSet);
209    OH_Huks_FreeParamSet(&hkdfFinishParamSet);
210
211    napi_value ret;
212    napi_create_int32(env, ohResult.errorCode, &ret);
213    return ret;
214}
215```
216