• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 密钥协商(ArkTS)
2
3
4以协商密钥类型为X25519 256,并密钥仅在HUKS内使用为例,完成密钥协商。具体的场景介绍及支持的算法规格,请参考[密钥生成支持的算法](huks-key-generation-overview.md#支持的算法)。
5
6
7## 开发步骤
8
9**生成密钥**
10
11设备A、设备B各自生成一个非对称密钥,具体请参考[密钥生成](huks-key-generation-overview.md)或[密钥导入](huks-key-import-overview.md)。
12
13密钥生成时,可指定参数TAG(可选),HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG:
14
15- HUKS_STORAGE_ONLY_USED_IN_HUKS:表示由该密钥协商出的密钥存储于HUKS中,由HUKS进行托管。
16
17- HUKS_STORAGE_KEY_EXPORT_ALLOWED(默认):表示由该密钥协商出的密钥直接导出给业务方,HUKS不对其进行托管服务。
18
19**导出密钥**
20
21设备A、B导出非对称密钥对的公钥材料,具体请参考[密钥导出](huks-export-key-arkts.md)。
22
23**密钥协商**
24
25设备A、B分别基于本端私钥和对端设备的公钥,协商出共享密钥。
26
27**删除密钥**
28
29当密钥废弃不用时,设备A、B均需要删除密钥,具体请参考[密钥删除](huks-delete-key-arkts.md)。
30
31```ts
32/*
33 *以下以X25519 256密钥的Promise操作使用为例
34 */
35 import huks from '@ohos.security.huks';
36 import { BusinessError } from '@ohos.base';
37 /*
38  * 确定密钥别名和封装密钥属性参数集
39  */
40 let srcKeyAliasFirst = "AgreeX25519KeyFirstAlias";
41 let srcKeyAliasSecond = "AgreeX25519KeySecondAlias";
42 let agreeX25519InData = 'AgreeX25519TestIndata';
43 let finishOutData: Uint8Array;
44 let handle: number;
45 let exportKey: Uint8Array;
46 let exportKeyFrist: Uint8Array;
47 let exportKeySecond: Uint8Array;
48 /* 集成生成密钥参数集 */
49 let properties: Array<huks.HuksParam> = new Array();
50 properties[0] = {
51     tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
52     value: huks.HuksKeyAlg.HUKS_ALG_X25519,
53 }
54 properties[1] = {
55     tag: huks.HuksTag.HUKS_TAG_PURPOSE,
56     value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE,
57 }
58 properties[2] = {
59     tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
60     value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256,
61 }
62 properties[3] = {
63     tag: huks.HuksTag.HUKS_TAG_DIGEST,
64     value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
65 }
66 properties[4] = {
67     tag: huks.HuksTag.HUKS_TAG_PADDING,
68     value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
69 }
70 properties[5] = {
71     tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
72     value: huks.HuksCipherMode.HUKS_MODE_CBC,
73 }
74 properties[6] = {
75     tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
76     value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
77 }
78 let HuksOptions: huks.HuksOptions = {
79     properties: properties,
80     inData: new Uint8Array(new Array())
81 }
82 /* 集成第一个协商参数集 */
83 let finishProperties: Array<huks.HuksParam> = new Array();
84 finishProperties[0] = {
85     tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
86     value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
87 }
88 finishProperties[1] = {
89     tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
90     value: true
91 }
92 finishProperties[2] = {
93     tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
94     value: huks.HuksKeyAlg.HUKS_ALG_AES,
95 }
96 finishProperties[3] = {
97     tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
98     value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
99 }
100 finishProperties[4] = {
101     tag: huks.HuksTag.HUKS_TAG_PURPOSE,
102     value:
103     huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
104     huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
105 }
106 finishProperties[5] = {
107     tag: huks.HuksTag.HUKS_TAG_DIGEST,
108     value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
109 }
110 finishProperties[6] = {
111     tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
112     value: StringToUint8Array(srcKeyAliasFirst+ 'final'),
113 }
114 finishProperties[7] = {
115     tag: huks.HuksTag.HUKS_TAG_PADDING,
116     value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
117 }
118 finishProperties[8] = {
119     tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
120     value: huks.HuksCipherMode.HUKS_MODE_ECB,
121 }
122 let finishOptionsFrist: huks.HuksOptions = {
123     properties: finishProperties,
124     inData: StringToUint8Array(agreeX25519InData)
125 }
126 /* 集成第二个协商参数集 */
127 let finishPropertiesSecond = [...finishProperties]
128 finishPropertiesSecond[6] = {
129    tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
130    value: StringToUint8Array(srcKeyAliasSecond + 'final'),
131 }
132 let finishOptionsSecond: huks.HuksOptions = {
133     properties: finishPropertiesSecond,
134     inData: StringToUint8Array(agreeX25519InData)
135 }
136 function StringToUint8Array(str:string) {
137     let arr: number[] = new Array();
138     for (let i = 0, j = str.length; i < j; ++i) {
139         arr.push(str.charCodeAt(i));
140     }
141 return new Uint8Array(arr);
142 }
143 class throwObject {
144     isThrow: boolean = false
145 }
146 /* 生成密钥 */
147 function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
148     return new Promise<void>((resolve, reject) => {
149         try {
150             huks.generateKeyItem(keyAlias, huksOptions, (error, data) => {
151                 if (error) {
152                     reject(error);
153                 } else {
154                     resolve(data);
155                 }
156             });
157         } catch (error) {
158             throwObject.isThrow = true;
159             throw(error as Error);
160         }
161     });
162 }
163 /* 调用generateKeyItem生成密钥 */
164 async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
165     console.info(`enter promise generateKeyItem`);
166     let throwObject:throwObject = {isThrow: false};
167     try {
168         await generateKeyItem(keyAlias, huksOptions, throwObject)
169         .then((data) => {
170             console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`);
171         })
172         .catch((error: BusinessError) => {
173             if (throwObject.isThrow) {
174                 throw(error as Error);
175             } else {
176                 console.error(`promise: generateKeyItem failed` + error);
177             }
178         });
179     } catch (error) {
180         console.error(`promise: generateKeyItem input arg invalid` + error);
181     }
182 }
183 /*初始化密钥会话接口,并获取一个句柄(必选)和挑战值(可选)*/
184 function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
185     return new Promise<huks.HuksSessionHandle>((resolve, reject) => {
186         try {
187             huks.initSession(keyAlias, huksOptions, (error, data) => {
188                 if (error) {
189                     reject(error);
190                 } else {
191                     resolve(data);
192                 }
193             });
194         } catch (error) {
195             throwObject.isThrow = true;
196             throw(error as Error);
197         }
198     });
199 }
200 /*调用initSession获取handle*/
201 async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
202     console.info(`enter promise doInit`);
203     let throwObject: throwObject = {isThrow: false};
204     try {
205         await initSession(keyAlias, huksOptions, throwObject)
206         .then ((data) => {
207             console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
208             handle = data.handle;
209         })
210         .catch((error: BusinessError) => {
211             if (throwObject.isThrow) {
212                 throw(error as Error);
213             } else {
214                 console.error(`promise: doInit failed` + error);
215             }
216         });
217     } catch (error) {
218         console.error(`promise: doInit input arg invalid` + error);
219     }
220 }
221 /* 分段添加密钥操作的数据并进行相应的密钥操作,输出处理数据 */
222 function updateSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject)  {
223     return new Promise<huks.HuksReturnResult>((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 }
238 /* 调用updateSession进行协商操作 */
239 async function publicUpdateFunc(handle: number, huksOptions: huks.HuksOptions) {
240     console.info(`enter promise doUpdate`);
241     let throwObject: throwObject = {isThrow: false};
242     try {
243         await updateSession(handle, huksOptions, throwObject)
244         .then ((data) => {
245             console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`);
246         })
247         .catch((error: BusinessError) => {
248             if (throwObject.isThrow) {
249                 throw(error as Error);
250             } else {
251                 console.error(`promise: doUpdate failed` + error);
252             }
253         });
254     } catch (error) {
255         console.error(`promise: doUpdate input arg invalid` + error);
256     }
257 }
258 /* 结束密钥会话并进行相应的密钥操作,输出处理数据 */
259 function finishSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject) {
260     return new Promise<huks.HuksReturnResult>((resolve, reject) => {
261         try {
262             huks.finishSession(handle, huksOptions, (error, data) =>{
263                 if (error) {
264                     reject(error);
265                 } else {
266                     resolve(data);
267                 }
268             });
269         } catch (error) {
270             throwObject.isThrow = true;
271             throw(error as Error);
272         }
273     });
274 }
275 /* 调用finishSession结束操作 */
276 async function publicFinishFunc(handle: number, huksOptions: huks.HuksOptions) {
277     console.info(`enter promise doFinish`);
278     let throwObject: throwObject = {isThrow: false};
279     try {
280         await finishSession(handle, huksOptions, throwObject)
281         .then ((data) => {
282             finishOutData = data.outData as Uint8Array;
283             console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
284         })
285         .catch((error: BusinessError) => {
286             if (throwObject.isThrow) {
287                 throw(error as Error);
288             } else {
289                 console.error(`promise: doFinish failed` + error);
290             }
291         });
292     } catch (error) {
293         console.error(`promise: doFinish input arg invalid` + error);
294     }
295 }
296 /* 导出密钥 */
297 function exportKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
298     return new Promise<huks.HuksReturnResult>((resolve, reject) => {
299         try {
300             huks.exportKeyItem(keyAlias, huksOptions, (error, data) => {
301                 if (error) {
302                     reject(error);
303                 } else {
304                     resolve(data);
305                 }
306             });
307         } catch (error) {
308             throwObject.isThrow = true;
309             throw(error as Error);
310         }
311     });
312 }
313 /* 调用exportKeyItem导出公钥操作 */
314 async function publicExportKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
315     console.info(`enter promise export`);
316     let throwObject: throwObject = {isThrow: false};
317     try {
318         await exportKeyItem(keyAlias, huksOptions, throwObject)
319         .then ((data) => {
320             console.info(`promise: exportKeyItem success, data = ${JSON.stringify(data)}`);
321             exportKey = data.outData as Uint8Array;
322         })
323         .catch((error: BusinessError) => {
324             if (throwObject.isThrow) {
325                 throw(error as Error);
326             } else {
327                 console.error(`promise: exportKeyItem failed` + error);
328             }
329         });
330     } catch (error) {
331         console.error(`promise: exportKeyItem input arg invalid` + error);
332     }
333 }
334 /* 删除密钥操作 */
335 function deleteKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
336     return new Promise<void>((resolve, reject) => {
337         try {
338             huks.deleteKeyItem(keyAlias, huksOptions, (error, data) => {
339                 if (error) {
340                     reject(error);
341                 } else {
342                     resolve(data);
343                 }
344             });
345         } catch (error) {
346             throwObject.isThrow = true;
347             throw(error as Error);
348         }
349     });
350 }
351 /* 调用deleteKeyItem删除密钥操作 */
352 async function publicDeleteKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
353     console.info(`enter promise deleteKeyItem`);
354     let throwObject: throwObject = {isThrow: false};
355     try {
356         await deleteKeyItem(keyAlias, huksOptions, throwObject)
357         .then ((data) => {
358            console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
359         })
360         .catch((error :BusinessError) => {
361             if (throwObject.isThrow) {
362                 throw(error as Error);
363             } else {
364                 console.error(`promise: deleteKeyItem failed` + error);
365             }
366         });
367     } catch (error) {
368         console.error(`promise: deletKeeyItem input arg invalid` + error);
369     }
370 }
371 async function testAgree() {
372     /* 1.确定密钥别名并集成并集成要参数集 A设备:srcKeyAliasFirst  B设备:srcKeyAliasSecond*/
373     /* 2.设备A生成密钥 */
374     await publicGenKeyFunc(srcKeyAliasFirst, HuksOptions);
375     /* 3.设备B生成密钥 */
376     await publicGenKeyFunc(srcKeyAliasSecond, HuksOptions);
377     /* 4.设备A、B导出非对称密钥的公钥 */
378     await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions);
379     exportKeyFrist = exportKey;
380     await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions);
381     exportKeySecond = exportKey;
382     /* 5.对第一个密钥进行协商(三段式)*/
383     await publicInitFunc(srcKeyAliasFirst, HuksOptions);
384     HuksOptions.inData = exportKeySecond;
385     await publicUpdateFunc(handle, HuksOptions);
386     await publicFinishFunc(handle, finishOptionsFrist);
387     /* 5.对第二个密钥进行协商(三段式) */
388     await publicInitFunc(srcKeyAliasSecond, HuksOptions);
389     HuksOptions.inData = exportKeyFrist;
390     await publicUpdateFunc(handle, HuksOptions);
391     await publicFinishFunc(handle, finishOptionsSecond);
392     /* 6.设备A、B删除密钥 */
393     await publicDeleteKeyFunc(srcKeyAliasFirst, HuksOptions);
394     await publicDeleteKeyFunc(srcKeyAliasSecond, HuksOptions);
395 }
396```
397