1# Key Derivation (ArkTS)
2
3
4This topic walks you through on how to derive a 256-bit key using HKDF. For details about the scenarios and supported algorithms, see [Supported Algorithms](huks-key-generation-overview.md#supported-algorithms).
5
6
7## How to Develop
8
9**Key Generation**
10
111. Set the key alias.
12
132. Initialize the key property set. You can set **HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** (optional) to specify how the key derived from this key is managed.
14
15    - If this tag is set to **HUKS_STORAGE_ONLY_USED_IN_HUKS**, the derived key is managed by HUKS. That is, the derived key is always in a secure environment throughout its lifecycle.
16
17    - If this tag is set to **HUKS_STORAGE_KEY_EXPORT_ALLOWED**, the derived key will be returned to the caller for management. That is, the service side ensures the key security.
18
19    - If this tag is not set, the derived key can be either managed by HUKS or returned to the caller for management. The key protection mode can be set in the subsequent key derivation on the service side.
20
213. Use [generateKeyItem](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksgeneratekeyitem9) to generate a key. For details, see [Key Generation](huks-key-generation-overview.md).
22
23Alternatively, you can [import a key](huks-key-import-overview.md).
24
25**Key Derivation**
26
271. Obtain the key alias and set the **HuksOptions** parameter.
28
29    You can set **HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG** to specify how the derived key is managed.
30
31    | Key Generation| Key Derivation| Specifications|
32    | -------- | -------- | -------- |
33    | HUKS_STORAGE_ONLY_USED_IN_HUKS | HUKS_STORAGE_ONLY_USED_IN_HUKS | The key is managed by HUKS.|
34    | HUKS_STORAGE_KEY_EXPORT_ALLOWED | HUKS_STORAGE_KEY_EXPORT_ALLOWED | The key is returned to the caller for management.|
35    | The tag is not set.| HUKS_STORAGE_ONLY_USED_IN_HUKS | The key is managed by HUKS.|
36    | The tag is not set.| HUKS_STORAGE_KEY_EXPORT_ALLOWED | The key is returned to the caller for management.|
37    | The tag is not set.| The tag is not set.| The key is returned to the caller for management.|
38
39    >**NOTE**<br>The tag value set in key derivation should not conflict with the tag value set in key generation. The above table lists only valid settings.
40
41
422. Use [initSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksinitsession9) to initialize a key session. The session handle is returned after the initialization.
43
443. Use [updateSession](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksupdatesession9) to process data.
45
464. Use [OH_Huks_FinishSession](../../reference/apis-universal-keystore-kit/_huks_key_api.md#oh_huks_finishsession) to derive a key.
47
48**Key Deletion**
49
50Use [deleteKeyItem](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksdeletekeyitem9) to delete the key that is not required. For details, see [Deleting a Key](huks-delete-key-arkts.md).
51## Development Cases
52### HKDF
53```ts
54/*
55 * Derive an HKDF key using promise-based APIs.
56 */
57import { huks } from '@kit.UniversalKeystoreKit';
58
59/*
60 * Set the key alias and encapsulate the key property set.
61 */
62let srcKeyAlias = "hkdf_Key";
63let deriveHkdfInData = "deriveHkdfTestIndata";
64let handle: number;
65let finishOutData: Uint8Array;
66let HuksKeyDeriveKeySize = 32;
67/* Set the parameter set used for key generation. */
68let properties: Array<huks.HuksParam> = [
69  {
70    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
71    value: huks.HuksKeyAlg.HUKS_ALG_AES,
72  }, {
73  tag: huks.HuksTag.HUKS_TAG_PURPOSE,
74  value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
75}, {
76  tag: huks.HuksTag.HUKS_TAG_DIGEST,
77  value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
78}, {
79  tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
80  value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
81}, {
82  tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
83  value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
84}];
85
86let huksOptions: huks.HuksOptions = {
87  properties: properties,
88  inData: new Uint8Array(new Array())
89}
90/* Set the parameter set used for init(). */
91let initProperties: Array<huks.HuksParam> = [{
92  tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
93  value: huks.HuksKeyAlg.HUKS_ALG_HKDF,
94}, {
95  tag: huks.HuksTag.HUKS_TAG_PURPOSE,
96  value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
97}, {
98  tag: huks.HuksTag.HUKS_TAG_DIGEST,
99  value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
100}, {
101  tag: huks.HuksTag.HUKS_TAG_DERIVE_KEY_SIZE,
102  value: HuksKeyDeriveKeySize,
103}];
104
105let initOptions: huks.HuksOptions = {
106  properties: initProperties,
107  inData: new Uint8Array(new Array())
108}
109/* Set the parameter set used for finish(). */
110let finishProperties: Array<huks.HuksParam> = [{
111  tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
112  value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
113}, {
114  tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
115  value: true,
116}, {
117  tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
118  value: huks.HuksKeyAlg.HUKS_ALG_AES,
119}, {
120  tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
121  value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
122}, {
123  tag: huks.HuksTag.HUKS_TAG_PURPOSE,
124  value:
125  huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
126  huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
127}, {
128  tag: huks.HuksTag.HUKS_TAG_DIGEST,
129  value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
130}, {
131  tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
132  value: StringToUint8Array(srcKeyAlias),
133}, {
134  tag: huks.HuksTag.HUKS_TAG_PADDING,
135  value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
136}, {
137  tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
138  value: huks.HuksCipherMode.HUKS_MODE_ECB,
139}];
140let finishOptions: huks.HuksOptions = {
141  properties: finishProperties,
142  inData: new Uint8Array(new Array())
143}
144
145function StringToUint8Array(str: String) {
146  let arr: number[] = new Array();
147  for (let i = 0, j = str.length; i < j; ++i) {
148    arr.push(str.charCodeAt(i));
149  }
150  return new Uint8Array(arr);
151}
152
153class throwObject {
154  isThrow = false;
155}
156
157function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
158  return new Promise<void>((resolve, reject) => {
159    try {
160      huks.generateKeyItem(keyAlias, huksOptions, (error, data) => {
161        if (error) {
162          reject(error);
163        } else {
164          resolve(data);
165        }
166      });
167    } catch (error) {
168      throwObject.isThrow = true;
169      throw (error as Error);
170    }
171  });
172}
173
174async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
175  console.info(`enter promise generateKeyItem`);
176  let throwObject: throwObject = { isThrow: false };
177  try {
178    await generateKeyItem(keyAlias, huksOptions, throwObject)
179      .then((data) => {
180        console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`);
181      })
182      .catch((error: Error) => {
183        if (throwObject.isThrow) {
184          throw (error as Error);
185        } else {
186          console.error(`promise: generateKeyItem failed, ${JSON.stringify(error)}`);
187        }
188      });
189  } catch (error) {
190    console.error(`promise: generateKeyItem input arg invalid, ${JSON.stringify(error)}`);
191  }
192}
193
194function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
195  return new Promise<huks.HuksSessionHandle>((resolve, reject) => {
196    try {
197      huks.initSession(keyAlias, huksOptions, (error, data) => {
198        if (error) {
199          reject(error);
200        } else {
201          resolve(data);
202        }
203      });
204    } catch (error) {
205      throwObject.isThrow = true;
206      throw (error as Error);
207    }
208  });
209}
210
211async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
212  console.info(`enter promise doInit`);
213  let throwObject: throwObject = { isThrow: false };
214  try {
215    await initSession(keyAlias, huksOptions, throwObject)
216      .then((data) => {
217        console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
218        handle = data.handle;
219      })
220      .catch((error: Error) => {
221        if (throwObject.isThrow) {
222          throw (error as Error);
223        } else {
224          console.error(`promise: doInit failed, ${JSON.stringify(error)}`);
225        }
226      });
227  } catch (error) {
228    console.error(`promise: doInit input arg invalid, ${JSON.stringify(error)}`);
229  }
230}
231
232function updateSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject) {
233  return new Promise<huks.HuksOptions>((resolve, reject) => {
234    try {
235      huks.updateSession(handle, huksOptions, (error, data) => {
236        if (error) {
237          reject(error);
238        } else {
239          resolve(data);
240        }
241      });
242    } catch (error) {
243      throwObject.isThrow = true;
244      throw (error as Error);
245    }
246  });
247}
248
249async function publicUpdateFunc(handle: number, huksOptions: huks.HuksOptions) {
250  console.info(`enter promise doUpdate`);
251  let throwObject: throwObject = { isThrow: false };
252  try {
253    await updateSession(handle, huksOptions, throwObject)
254      .then((data) => {
255        console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`);
256      })
257      .catch((error: Error) => {
258        if (throwObject.isThrow) {
259          throw (error as Error);
260        } else {
261          console.error(`promise: doUpdate failed, ${JSON.stringify(error)}`);
262        }
263      });
264  } catch (error) {
265    console.error(`promise: doUpdate input arg invalid, ${JSON.stringify(error)}`);
266  }
267}
268
269function finishSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject) {
270  return new Promise<huks.HuksReturnResult>((resolve, reject) => {
271    try {
272      huks.finishSession(handle, huksOptions, (error, data) => {
273        if (error) {
274          reject(error);
275        } else {
276          resolve(data);
277        }
278      });
279    } catch (error) {
280      throwObject.isThrow = true;
281      throw (error as Error);
282    }
283  });
284}
285
286async function publicFinishFunc(handle: number, huksOptions: huks.HuksOptions) {
287  console.info(`enter promise doFinish`);
288  let throwObject: throwObject = { isThrow: false };
289  try {
290    await finishSession(handle, huksOptions, throwObject)
291      .then((data) => {
292        finishOutData = data.outData as Uint8Array;
293        console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
294      })
295      .catch((error: Error) => {
296        if (throwObject.isThrow) {
297          throw (error as Error);
298        } else {
299          console.error(`promise: doFinish failed, ${JSON.stringify(error)}`);
300        }
301      });
302  } catch (error) {
303    console.error(`promise: doFinish input arg invalid, ${JSON.stringify(error)}`);
304  }
305}
306
307function deleteKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
308  return new Promise<void>((resolve, reject) => {
309    try {
310      huks.deleteKeyItem(keyAlias, huksOptions, (error, data) => {
311        if (error) {
312          reject(error);
313        } else {
314          resolve(data);
315        }
316      });
317    } catch (error) {
318      throwObject.isThrow = true;
319      throw (error as Error);
320    }
321  });
322}
323
324async function publicDeleteKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
325  console.info(`enter promise deleteKeyItem`);
326  let throwObject: throwObject = { isThrow: false };
327  try {
328    await deleteKeyItem(keyAlias, huksOptions, throwObject)
329      .then((data) => {
330        console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
331      })
332      .catch((error: Error) => {
333        if (throwObject.isThrow) {
334          throw (error as Error);
335        } else {
336          console.error(`promise: deleteKeyItem failed, ${JSON.stringify(error)}`);
337        }
338      });
339  } catch (error) {
340    console.error(`promise: deleteKeyItem input arg invalid, ${JSON.stringify(error)}`);
341  }
342}
343
344async function testDerive() {
345  /* Generate a key. */
346  await publicGenKeyFunc(srcKeyAlias, huksOptions);
347  /* Perform key derivation. */
348  await publicInitFunc(srcKeyAlias, initOptions);
349  initOptions.inData = StringToUint8Array(deriveHkdfInData);
350  await publicUpdateFunc(handle, initOptions);
351  await publicFinishFunc(handle, finishOptions);
352  await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
353}
354```
355### PBKDF2
356
357```ts
358/*
359 * Derive a PBKDF2 key using promise-based APIs.
360 */
361import { huks } from '@kit.UniversalKeystoreKit';
362
363/*
364 * Set the key alias and encapsulate the key property set.
365 */
366let srcKeyAlias = "pbkdf2_Key";
367let salt = "mySalt";
368let iterationCount = 10000;
369let derivedKeySize = 32;
370let handle: number;
371let finishOutData: Uint8Array;
372
373/* Set the parameter set used for key generation. */
374let properties: Array<huks.HuksParam> = [
375  {
376    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
377    value: huks.HuksKeyAlg.HUKS_ALG_AES,
378  }, {
379    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
380    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
381  }, {
382    tag: huks.HuksTag.HUKS_TAG_DIGEST,
383    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
384  }, {
385    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
386    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
387  }, {
388    tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
389    value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
390  }
391];
392
393let huksOptions: huks.HuksOptions = {
394  properties: properties,
395  inData: new Uint8Array(new Array())
396}
397
398/* Set the parameter set used for init(). */
399let initProperties: Array<huks.HuksParam> = [
400  {
401    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
402    value: huks.HuksKeyAlg.HUKS_ALG_PBKDF2,
403  }, {
404    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
405    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
406  }, {
407    tag: huks.HuksTag.HUKS_TAG_DIGEST,
408    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
409  }, {
410    tag: huks.HuksTag.HUKS_TAG_DERIVE_KEY_SIZE,
411    value: derivedKeySize,
412  }, {
413    tag: huks.HuksTag.HUKS_TAG_ITERATION,
414    value: iterationCount,
415  }, {
416    tag: huks.HuksTag.HUKS_TAG_SALT,
417    value: StringToUint8Array(salt),
418  }
419];
420
421let initOptions: huks.HuksOptions = {
422  properties: initProperties,
423  inData: new Uint8Array(new Array())
424}
425
426/* Set the parameter set used for finish(). */
427let finishProperties: Array<huks.HuksParam> = [
428  {
429    tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG,
430    value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS,
431  }, {
432    tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
433    value: true,
434  }, {
435    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
436    value: huks.HuksKeyAlg.HUKS_ALG_AES,
437  }, {
438    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
439    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
440  }, {
441    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
442    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
443  }, {
444    tag: huks.HuksTag.HUKS_TAG_DIGEST,
445    value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
446  }, {
447    tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
448    value: StringToUint8Array(srcKeyAlias),
449  }, {
450    tag: huks.HuksTag.HUKS_TAG_PADDING,
451    value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
452  }, {
453    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
454    value: huks.HuksCipherMode.HUKS_MODE_ECB,
455  }
456];
457
458let finishOptions: huks.HuksOptions = {
459  properties: finishProperties,
460  inData: new Uint8Array(new Array())
461}
462
463function StringToUint8Array(str: String) {
464  let arr: number[] = new Array();
465  for (let i = 0, j = str.length; i < j; ++i) {
466    arr.push(str.charCodeAt(i));
467  }
468  return new Uint8Array(arr);
469}
470
471class throwObject {
472  isThrow = false;
473}
474
475function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
476  return new Promise<void>((resolve, reject) => {
477    try {
478      huks.generateKeyItem(keyAlias, huksOptions, (error, data) => {
479        if (error) {
480          reject(error);
481        } else {
482          resolve(data);
483        }
484      });
485    } catch (error) {
486      throwObject.isThrow = true;
487      throw (error as Error);
488    }
489  });
490}
491
492async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
493  console.info(`enter promise generateKeyItem`);
494  let throwObject: throwObject = { isThrow: false };
495  try {
496    await generateKeyItem(keyAlias, huksOptions, throwObject)
497      .then((data) => {
498        console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`);
499      })
500      .catch((error: Error) => {
501        if (throwObject.isThrow) {
502          throw (error as Error);
503        } else {
504          console.error(`promise: generateKeyItem failed, ${JSON.stringify(error)}`);
505        }
506      });
507  } catch (error) {
508    console.error(`promise: generateKeyItem input arg invalid, ${JSON.stringify(error)}`);
509  }
510}
511
512function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
513  return new Promise<huks.HuksSessionHandle>((resolve, reject) => {
514    try {
515      huks.initSession(keyAlias, huksOptions, (error, data) => {
516        if (error) {
517          reject(error);
518        } else {
519          resolve(data);
520        }
521      });
522    } catch (error) {
523      throwObject.isThrow = true;
524      throw (error as Error);
525    }
526  });
527}
528
529async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
530  console.info(`enter promise doInit`);
531  let throwObject: throwObject = { isThrow: false };
532  try {
533    await initSession(keyAlias, huksOptions, throwObject)
534      .then((data) => {
535        console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
536        handle = data.handle;
537      })
538      .catch((error: Error) => {
539        if (throwObject.isThrow) {
540          throw (error as Error);
541        } else {
542          console.error(`promise: doInit failed, ${JSON.stringify(error)}`);
543        }
544      });
545  } catch (error) {
546    console.error(`promise: doInit input arg invalid, ${JSON.stringify(error)}`);
547  }
548}
549
550function updateSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject) {
551  return new Promise<huks.HuksOptions>((resolve, reject) => {
552    try {
553      huks.updateSession(handle, huksOptions, (error, data) => {
554        if (error) {
555          reject(error);
556        } else {
557          resolve(data);
558        }
559      });
560    } catch (error) {
561      throwObject.isThrow = true;
562      throw (error as Error);
563    }
564  });
565}
566
567async function publicUpdateFunc(handle: number, huksOptions: huks.HuksOptions) {
568  console.info(`enter promise doUpdate`);
569  let throwObject: throwObject = { isThrow: false };
570  try {
571    await updateSession(handle, huksOptions, throwObject)
572      .then((data) => {
573        console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`);
574      })
575      .catch((error: Error) => {
576        if (throwObject.isThrow) {
577          throw (error as Error);
578        } else {
579          console.error(`promise: doUpdate failed, ${JSON.stringify(error)}`);
580        }
581      });
582  } catch (error) {
583    console.error(`promise: doUpdate input arg invalid, ${JSON.stringify(error)}`);
584  }
585}
586
587function finishSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject) {
588  return new Promise<huks.HuksReturnResult>((resolve, reject) => {
589    try {
590      huks.finishSession(handle, huksOptions, (error, data) => {
591        if (error) {
592          reject(error);
593        } else {
594          resolve(data);
595        }
596      });
597    } catch (error) {
598      throwObject.isThrow = true;
599      throw (error as Error);
600    }
601  });
602}
603
604async function publicFinishFunc(handle: number, huksOptions: huks.HuksOptions) {
605  console.info(`enter promise doFinish`);
606  let throwObject: throwObject = { isThrow: false };
607  try {
608    await finishSession(handle, huksOptions, throwObject)
609      .then((data) => {
610        finishOutData = data.outData as Uint8Array;
611        console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
612      })
613      .catch((error: Error) => {
614        if (throwObject.isThrow) {
615          throw (error as Error);
616        } else {
617          console.error(`promise: doFinish failed, ${JSON.stringify(error)}`);
618        }
619      });
620  } catch (error) {
621    console.error(`promise: doFinish input arg invalid, ${JSON.stringify(error)}`);
622  }
623}
624
625function deleteKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
626  return new Promise<void>((resolve, reject) => {
627    try {
628      huks.deleteKeyItem(keyAlias, huksOptions, (error, data) => {
629        if (error) {
630          reject(error);
631        } else {
632          resolve(data);
633        }
634      });
635    } catch (error) {
636      throwObject.isThrow = true;
637      throw (error as Error);
638    }
639  });
640}
641
642async function publicDeleteKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
643  console.info(`enter promise deleteKeyItem`);
644  let throwObject: throwObject = { isThrow: false };
645  try {
646    await deleteKeyItem(keyAlias, huksOptions, throwObject)
647      .then((data) => {
648        console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
649      })
650      .catch((error: Error) => {
651        if (throwObject.isThrow) {
652          throw (error as Error);
653        } else {
654          console.error(`promise: deleteKeyItem failed, ${JSON.stringify(error)}`);
655        }
656      });
657  } catch (error) {
658    console.error(`promise: deleteKeyItem input arg invalid, ${JSON.stringify(error)}`);
659  }
660}
661
662async function testDerive() {
663  /* Generate a key. */
664  await publicGenKeyFunc(srcKeyAlias, huksOptions);
665  /* Perform key derivation. */
666  await publicInitFunc(srcKeyAlias, initOptions);
667  await publicUpdateFunc(handle, initOptions);
668  await publicFinishFunc(handle, finishOptions);
669  await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
670}
671```
672