• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 密钥派生(ArkTS)
2
3
4以HKDF256密钥为例,完成密钥派生。具体的场景介绍及支持的算法规格,请参考[密钥生成支持的算法](huks-key-generation-overview.md#支持的算法)。
5
6
7## 开发步骤
8
9**生成密钥**
10
111. 指定密钥别名。
12
132. 初始化密钥属性集,可指定参数TAG(可选),HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG:
14   - HUKS_STORAGE_ONLY_USED_IN_HUKS:表示由该密钥派生出的密钥存储于HUKS中,由HUKS进行托管。
15   - HUKS_STORAGE_KEY_EXPORT_ALLOWED(默认):表示由该密钥派生出的密钥直接导出给业务方,HUKS不对其进行托管服务。
16
173. 调用[generateKeyItem](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksgeneratekeyitem9)生成密钥,具体请参考[密钥生成](huks-key-generation-overview.md)。
18
19除此之外,开发者也可以参考[密钥导入](huks-key-import-overview.md),导入已有的密钥。
20
21**密钥派生**
22
231. 获取密钥别名、指定对应的属性参数HuksOptions。
24
252. 调用[initSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksinitsession9)初始化密钥会话,并获取会话的句柄handle。
26
273. 调用[updateSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksupdatesession9)更新密钥会话。
28
294. 调用[finishSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksfinishsession9)结束密钥会话,完成派生。
30
31**删除密钥**
32
33当密钥废弃不用时,需要调用[deleteKeyItem](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksdeletekeyitem9)删除密钥,具体请参考[密钥删除](huks-delete-key-arkts.md)。
34
35```ts
36/*
37 * 以下以HKDF256密钥的Promise操作使用为例
38 */
39import huks from '@ohos.security.huks';
40import { BusinessError } from '@ohos.base';
41/*
42 * 确定密钥别名和封装密钥属性参数集
43 */
44let srcKeyAlias = "hkdf_Key";
45let deriveHkdfInData = "deriveHkdfTestIndata";
46let handle:number;
47let finishOutData:Uint8Array;
48let HuksKeyDeriveKeySize = 32;
49/* 集成生成密钥参数集 */
50let properties:Array<huks.HuksParam> = new Array();
51properties[0] = {
52    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
53    value: huks.HuksKeyAlg.HUKS_ALG_AES,
54}
55properties[1] = {
56    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
57    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
58}
59properties[2] = {
60    tag: huks.HuksTag.HUKS_TAG_DIGEST,
61    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
62}
63properties[3] = {
64    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
65    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
66}
67properties[4] = {
68    tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
69    value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
70}
71let huksOptions:huks.HuksOptions = {
72    properties: properties,
73    inData: new Uint8Array(new Array())
74}
75/* 集成init时密钥参数集 */
76let initProperties:Array<huks.HuksParam> = new Array();
77initProperties[0] = {
78    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
79    value: huks.HuksKeyAlg.HUKS_ALG_HKDF,
80}
81initProperties[1] = {
82    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
83    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
84}
85initProperties[2] = {
86    tag: huks.HuksTag.HUKS_TAG_DIGEST,
87    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
88}
89initProperties[3] = {
90    tag: huks.HuksTag.HUKS_TAG_DERIVE_KEY_SIZE,
91    value: HuksKeyDeriveKeySize,
92}
93let initOptions:huks.HuksOptions = {
94    properties: initProperties,
95    inData: new Uint8Array(new Array())
96}
97/* 集成finish时密钥参数集 */
98let finishProperties:Array<huks.HuksParam> = new Array();
99finishProperties[0] = {
100    tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
101    value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
102}
103finishProperties[1] = {
104    tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
105    value: true,
106}
107finishProperties[2] = {
108    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
109    value: huks.HuksKeyAlg.HUKS_ALG_AES,
110}
111finishProperties[3] = {
112    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
113    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
114}
115finishProperties[4] = {
116    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
117    value:
118    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
119    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
120}
121finishProperties[5] = {
122    tag: huks.HuksTag.HUKS_TAG_DIGEST,
123    value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
124}
125finishProperties[6] = {
126    tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
127    value: StringToUint8Array(srcKeyAlias),
128}
129finishProperties[7] = {
130    tag: huks.HuksTag.HUKS_TAG_PADDING,
131    value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
132}
133finishProperties[8] = {
134    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
135    value: huks.HuksCipherMode.HUKS_MODE_ECB,
136}
137let finishOptions:huks.HuksOptions = {
138    properties: finishProperties,
139    inData: new Uint8Array(new Array())
140}
141function StringToUint8Array(str:String) {
142    let arr:number[]=new Array();
143    for (let i = 0, j = str.length; i < j; ++i) {
144        arr.push(str.charCodeAt(i));
145    }
146    return new Uint8Array(arr);
147}
148class throwObject{
149    isThrow=false;
150}
151function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject:throwObject) {
152    return new Promise<void>((resolve, reject) => {
153        try {
154            huks.generateKeyItem(keyAlias, huksOptions, (error, data)=> {
155                if (error) {
156                    reject(error);
157                } else {
158                    resolve(data);
159                }
160            });
161        } catch (error) {
162            throwObject.isThrow = true;
163            throw(error as Error);
164        }
165    });
166}
167async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
168    console.info(`enter promise generateKeyItem`);
169    let throwObject:throwObject = {isThrow: false};
170    try {
171        await generateKeyItem(keyAlias, huksOptions, throwObject)
172        .then((data) => {
173            console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`);
174        })
175        .catch((error:BusinessError) => {
176            if (throwObject.isThrow) {
177                throw(error as Error);
178            } else {
179                console.error(`promise: generateKeyItem failed` + error);
180            }
181        });
182    } catch (error) {
183        console.error(`promise: generateKeyItem input arg invalid` + error);
184    }
185}
186function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject:throwObject) {
187    return new Promise<huks.HuksSessionHandle>((resolve, reject) => {
188        try {
189            huks.initSession(keyAlias, huksOptions, (error, data)=> {
190                if (error) {
191                    reject(error);
192                } else {
193                    resolve(data);
194                }
195            });
196        } catch (error) {
197            throwObject.isThrow = true;
198            throw(error as Error);
199        }
200    });
201}
202async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
203    console.info(`enter promise doInit`);
204    let throwObject:throwObject = {isThrow: false};
205    try {
206        await initSession(keyAlias, huksOptions, throwObject)
207        .then ((data) => {
208            console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
209            handle = data.handle;
210        })
211        .catch((error:BusinessError) => {
212            if (throwObject.isThrow) {
213                throw(error as Error);
214            } else {
215                console.error(`promise: doInit failed` + error);
216            }
217        });
218    } catch (error) {
219        console.error(`promise: doInit input arg invalid` + error);
220    }
221}
222function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject:throwObject) {
223    return new Promise<huks.HuksOptions>((resolve, reject) => {
224        try {
225            huks.updateSession(handle, huksOptions, (error, data)=> {
226                if (error) {
227                    reject(error);
228                } else {
229                    resolve(data);
230                }
231            });
232        } catch (error) {
233            throwObject.isThrow = true;
234            throw(error as Error);
235        }
236    });
237}
238async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
239    console.info(`enter promise doUpdate`);
240    let throwObject:throwObject = {isThrow: false};
241    try {
242        await updateSession(handle, huksOptions, throwObject)
243        .then ((data) => {
244            console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`);
245        })
246        .catch((error:BusinessError) => {
247            if (throwObject.isThrow) {
248                throw(error as Error);
249            } else {
250                console.error(`promise: doUpdate failed` + error);
251            }
252        });
253    } catch (error) {
254        console.error(`promise: doUpdate input arg invalid` + error);
255    }
256}
257function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject:throwObject) {
258    return new Promise<huks.HuksReturnResult>((resolve, reject) => {
259        try {
260            huks.finishSession(handle, huksOptions, (error, data)=> {
261                if (error) {
262                    reject(error);
263                } else {
264                    resolve(data);
265                }
266            });
267        } catch (error) {
268            throwObject.isThrow = true;
269            throw(error as Error);
270        }
271    });
272}
273async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
274    console.info(`enter promise doFinish`);
275    let throwObject:throwObject = {isThrow: false};
276    try {
277        await finishSession(handle, huksOptions, throwObject)
278        .then ((data) => {
279            finishOutData = data.outData as Uint8Array;
280            console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
281        })
282        .catch((error:BusinessError) => {
283            if (throwObject.isThrow) {
284                throw(error as Error);
285            } else {
286                console.error(`promise: doFinish failed` + error);
287            }
288        });
289    } catch (error) {
290        console.error(`promise: doFinish input arg invalid` + error);
291    }
292}
293function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject:throwObject) {
294    return new Promise<void>((resolve, reject) => {
295        try {
296            huks.deleteKeyItem(keyAlias, huksOptions, (error, data)=> {
297                if (error) {
298                    reject(error);
299                } else {
300                    resolve(data);
301                }
302            });
303        } catch (error) {
304            throwObject.isThrow = true;
305            throw(error as Error);
306        }
307    });
308}
309async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
310    console.info(`enter promise deleteKeyItem`);
311    let throwObject:throwObject = {isThrow: false};
312    try {
313        await deleteKeyItem(keyAlias, huksOptions, throwObject)
314        .then ((data) => {
315            console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
316        })
317        .catch((error:BusinessError) => {
318            if (throwObject.isThrow) {
319                throw(error as Error);
320            } else {
321                console.error(`promise: deleteKeyItem failed` + error);
322            }
323        });
324    } catch (error) {
325        console.error(`promise: deletKeeyItem input arg invalid` + error);
326    }
327}
328async function testDerive() {
329    /* 生成密钥 */
330    await publicGenKeyFunc(srcKeyAlias, huksOptions);
331    /* 进行派生操作 */
332    await publicInitFunc(srcKeyAlias, initOptions);
333    initOptions.inData = StringToUint8Array(deriveHkdfInData);
334    await publicUpdateFunc(handle, initOptions);
335    await publicFinishFunc(handle, finishOptions);
336    await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
337}
338```
339