• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HUKS Development
2
3OpenHarmony Universal KeyStore (HUKS) provides KeyStore (KS) capabilities for applications, including key management and key cryptography operations. HUKS also provides APIs for applications to import or generate keys.
4
5> **NOTE**
6>
7> This document is based on API version 9 and applies only to ArkTS development.
8
9### Prerequisites
10
11The HUKS module must have been imported.
12
13```ts
14import huks from '@ohos.security.huks'
15```
16
17### Generating a Key
18
19Generate a key for an application by specifying the alias and key parameters.
20
21> **NOTE**
22>
23> - When a key is used if the parameters passed in does not comply with the parameters passed in during the key generation, the parameter verification will fail.
24>
25> - If an optional parameter required by the algorithm is not passed in during the key generation process, it must be passed in when the key is used.
26
27**Supported Key Types**
28
29The following lists the mandatory parameters for key generation, including the key algorithm, key length, and key usage.
30
31| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE                                            | HUKS_ALG_PURPOSE                                             |
32| ------------------ | :----------------------------------------------------------- | ------------------------------------------------------------ |
33| HUKS_ALG_RSA       | HUKS_RSA_KEY_SIZE_512 HUKS_RSA_KEY_SIZE_768  HUKS_RSA_KEY_SIZE_1024  HUKS_RSA_KEY_SIZE_2048  HUKS_RSA_KEY_SIZE_3072 HUKS_RSA_KEY_SIZE_4096 | HUKS_KEY_PURPOSE_ENCRYPT  HUKS_KEY_PURPOSE_DECRYPT HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY |
34| HUKS_ALG_AES       | HUKS_AES_KEY_SIZE_128 HUKS_AES_KEY_SIZE_192 HUKS_AES_KEY_SIZE_256 | HUKS_KEY_PURPOSE_ENCRYPT  HUKS_KEY_PURPOSE_DECRYPT HUKS_KEY_PURPOSE_DERIVE |
35| HUKS_ALG_ECC       | HUKS_ECC_KEY_SIZE_224 HUKS_ECC_KEY_SIZE_256 HUKS_ECC_KEY_SIZE_384 HUKS_ECC_KEY_SIZE_521 | HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY               |
36| HUKS_ALG_X25519    | HUKS_CURVE25519_KEY_SIZE_256                                 | HUKS_KEY_PURPOSE_AGREE                                       |
37| HUKS_ALG_ED25519   | HUKS_CURVE25519_KEY_SIZE_256                                 | HUKS_KEY_PURPOSE_SIGN   HUKS_KEY_PURPOSE_VERIFY              |
38| HUKS_ALG_DSA       | HUKS_RSA_KEY_SIZE_1024                                       | HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY               |
39| HUKS_ALG_DH        | HUKS_DH_KEY_SIZE_2048 HUKS_DH_KEY_SIZE_3072 HUKS_DH_KEY_SIZE_4096 | HUKS_KEY_PURPOSE_AGREE                                       |
40| HUKS_ALG_ECDH      | HUKS_ECC_KEY_SIZE_224 HUKS_ECC_KEY_SIZE_256 HUKS_ECC_KEY_SIZE_384 HUKS_ECC_KEY_SIZE_521 | HUKS_KEY_PURPOSE_AGREE                                       |
41| HUKS_ALG_SM2       | HUKS_SM2_KEY_SIZE_256                                        | HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY               |
42| HUKS_ALG_SM4       | HUKS_SM4_KEY_SIZE_128                                        | HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT         |
43
44Before you get started, understand the following variables:
45
46| Parameter          | Type       | Mandatory| Description                                                        |
47| ---------------- | ----------- | ---- | ------------------------------------------------------------ |
48| genKeyAlias      | string      | Yes  | Alias of the key generated.                                            |
49| genKeyProperties | HuksOptions | Yes  | Tags required for generating the key. The key algorithm, key usage, and key length are mandatory.|
50
51For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
52
53```ts
54/* Generate an ECC key of 256 bits. */
55let keyAlias = 'keyAlias';
56let properties = new Array();
57// Mandatory parameter.
58properties[0] = {
59    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
60    value: huks.HuksKeyAlg.HUKS_ALG_ECC
61};
62// Mandatory parameter.
63properties[1] = {
64    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
65    value: huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256
66};
67// Mandatory parameter.
68properties[2] = {
69    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
70    value:
71    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN |
72    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY
73};
74// Optional parameter.
75properties[3] = {
76    tag: huks.HuksTag.HUKS_TAG_DIGEST,
77    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
78};
79let options = {
80    properties: properties
81};
82try {
83    huks.generateKeyItem(keyAlias, options, function (error, data) {
84        if (error) {
85            console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
86        } else {
87            console.info(`callback: generateKeyItem key success`);
88        }
89    });
90} catch (error) {
91    console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
92}
93```
94
95
96
97### Key Import and Export
98
99The **HUKS** module allows the public key of its own asymmetric key (public and private key pair) to be exported based on the key alias.
100
101The **HUKS** module also supports import of external keys. Except the public keys of asymmetric keys, the keys imported into the HUKS cannot be exported in their lifecycle. If the alias of the key to be imported already exists in HUKS, the newly imported key will overwrite the existing one.
102
103The development procedure is as follows:
104
1051. Generate a key.
1062. Export the key.
1073. Import the key.
108
109**Supported Types of Keys to Import**
110
111AES128, AES192, AES256, RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512, ECC224, ECC256, ECC384, ECC521, Curve25519, DSA, SM2, SM3, SM4
112
113**Supported Types of Keys to Export**
114
115RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, ECC224, ECC256, ECC384, ECC521, Curve25519, DSA, SM2
116
117> **NOTE**<br>
118>
119> The key alias cannot exceed 64 bytes.
120
121Before you get started, understand the following variables:
122
123| Parameter        | Type       | Mandatory| Description                    |
124| -------------- | ----------- | ---- | ------------------------ |
125| exportKeyAlias | string      | Yes  | Alias of the key to generate.          |
126| importKeyAlias | string      | Yes  | Alias of the key to import.          |
127| huksOptions    | HuksOptions | Yes  | Tags required for generating the key.|
128| encryptOptions | HuksOptions | Yes  | Tags required for importing the key.|
129
130For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
131
132**Example**
133
134```ts
135/* Export an RSA512 key and import DH2048, RSA512, x25519, and ECC256 keys.*/
136import huks from '@ohos.security.huks';
137
138function StringToUint8Array(str) {
139    let arr = [];
140    for (let i = 0, j = str.length; i < j; ++i) {
141        arr.push(str.charCodeAt(i));
142    }
143    return new Uint8Array(arr);
144}
145
146function Uint8ArrayToString(fileData) {
147    let dataString = '';
148    for (let i = 0; i < fileData.length; i++) {
149        dataString += String.fromCharCode(fileData[i]);
150    }
151    return dataString;
152}
153
154function Uint32ToUint8(value) {
155    let arr = new Uint8Array(4 * value.length);
156    for (let i = 0, j = value.length; i < j; i++) {
157        arr[i * 4+3] = (value[i] >> 24) & 0xFF;
158        arr[i * 4+2] = (value[i] >> 16) & 0xFF;
159        arr[i * 4+1] = (value[i] >> 8) & 0xFF;
160        arr[i*4] = (value[i]) & 0xFF;
161    }
162    return arr;
163}
164
165async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
166    console.info(`enter callback generateKeyItem`);
167    try {
168        await generateKeyItem(keyAlias, huksOptions)
169            .then((data) => {
170                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
171            })
172            .catch(error => {
173                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
174            });
175    } catch (error) {
176        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
177    }
178}
179
180function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) {
181    return new Promise((resolve, reject) => {
182        try {
183            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
184                if (error) {
185                    reject(error);
186                } else {
187                    resolve(data);
188                }
189            });
190        } catch (error) {
191            throw (error);
192        }
193    });
194}
195
196async function publicExportKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
197    console.info(`enter callback export`);
198    try {
199        await exportKeyItem(keyAlias, huksOptions)
200            .then((data) => {
201                console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`);
202            })
203            .catch(error => {
204                console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`);
205            });
206    } catch (error) {
207        console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
208    }
209}
210
211function exportKeyItem(keyAlias: string, huksOptions: huks.HuksOptions): Promise<huks.HuksReturnResult> {
212    return new Promise((resolve, reject) => {
213        try {
214            huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
215                if (error) {
216                    reject(error);
217                 } else {
218                    resolve(data);
219                }
220            });
221        } catch (error) {
222            throw (error);
223        }
224    });
225}
226
227async function publicImportKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
228    console.info(`enter promise importKeyItem`);
229    try {
230        await importKeyItem(keyAlias, huksOptions)
231            .then((data) => {
232                console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`);
233            })
234            .catch(error => {
235                console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`);
236            });
237    } catch (error) {
238        console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
239    }
240}
241
242function importKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) {
243    return new Promise((resolve, reject) => {
244        try {
245            huks.importKeyItem(keyAlias, huksOptions, function (error, data) {
246                if (error) {
247                    reject(error);
248                } else {
249                   resolve(data);
250                }
251            });
252        } catch (error) {
253            throw (error);
254        }
255    });
256}
257
258async function publicDeleteKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
259    console.info(`enter callback deleteKeyItem`);
260    try {
261        await deleteKeyItem(keyAlias, huksOptions)
262            .then((data) => {
263                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
264            })
265            .catch(error => {
266                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
267            });
268    } catch (error) {
269        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
270    }
271}
272
273function deleteKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) {
274    return new Promise((resolve, reject) => {
275        try {
276            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
277                if (error) {
278                    reject(error);
279                } else {
280                    resolve(data);
281                }
282            });
283        } catch (error) {
284            throw (error);
285        }
286    });
287}
288
289// Export the RSA key.
290async function testExportRsa() {
291    let exportKeyAlias = 'export_rsa_key';
292    /* Configure the parameters for generating the key. */
293    let exportProperties = new Array();
294    exportProperties[0] = {
295        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
296        value: huks.HuksKeyAlg.HUKS_ALG_RSA
297    }
298    exportProperties[1] = {
299        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
300        value:
301        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
302        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
303    }
304    exportProperties[2] = {
305        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
306        value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512
307    }
308    exportProperties[3] = {
309        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
310        value: huks.HuksCipherMode.HUKS_MODE_ECB
311    }
312    exportProperties[4] = {
313        tag: huks.HuksTag.HUKS_TAG_PADDING,
314        value: huks.HuksKeyPadding.HUKS_PADDING_PKCS1_V1_5
315    }
316    exportProperties[5] = {
317        tag: huks.HuksTag.HUKS_TAG_DIGEST,
318        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
319    }
320    let huksOptions = {
321        properties: exportProperties,
322        inData: new Uint8Array(new Array())
323    }
324
325    /* Generate a key. */
326    await publicGenKeyFunc(exportKeyAlias, huksOptions);
327
328    /* Export the key. */
329    await publicExportKeyFunc(exportKeyAlias, huksOptions);
330    await publicDeleteKeyFunc(exportKeyAlias, huksOptions);
331}
332
333// DH key
334let g_dhPubData = new Uint8Array([
335    0x8a, 0xbf, 0x16, 0x67, 0x1b, 0x92, 0x4b, 0xf2, 0xe0, 0x02, 0xc5, 0x1f, 0x84, 0x00, 0xf8, 0x93,
336    0x0f, 0x74, 0xe7, 0x0f, 0xba, 0x78, 0x30, 0xa8, 0x2d, 0x92, 0xef, 0x9b, 0x80, 0xeb, 0x76, 0xea,
337    0x26, 0x74, 0x72, 0x63, 0x6a, 0x27, 0xc3, 0x8f, 0xcf, 0xbe, 0x82, 0xa2, 0x8b, 0xdc, 0x65, 0x58,
338    0xe3, 0xff, 0x29, 0x97, 0xad, 0xb3, 0x4a, 0x2c, 0x50, 0x08, 0xb5, 0x68, 0xe1, 0x90, 0x5a, 0xdc,
339    0x48, 0xb3, 0x6b, 0x7a, 0xce, 0x2e, 0x81, 0x3d, 0x38, 0x35, 0x59, 0xdc, 0x39, 0x8a, 0x97, 0xfe,
340    0x20, 0x86, 0x20, 0xdb, 0x55, 0x38, 0x23, 0xca, 0xb5, 0x5b, 0x61, 0x00, 0xdc, 0x45, 0xe2, 0xa1,
341    0xf4, 0x1e, 0x7b, 0x01, 0x7a, 0x84, 0x36, 0xa4, 0xa8, 0x1c, 0x0d, 0x3d, 0xde, 0x57, 0x66, 0x73,
342    0x4e, 0xaf, 0xee, 0xb0, 0xb0, 0x69, 0x0c, 0x13, 0xba, 0x76, 0xff, 0x2e, 0xb6, 0x16, 0xf9, 0xfc,
343    0xd6, 0x09, 0x5b, 0xc7, 0x37, 0x65, 0x84, 0xd5, 0x82, 0x8a, 0xd7, 0x5b, 0x57, 0xe3, 0x0e, 0x89,
344    0xbe, 0x05, 0x05, 0x55, 0x2e, 0x9f, 0x94, 0x8a, 0x53, 0xdc, 0xb7, 0x00, 0xb2, 0x6a, 0x7b, 0x8e,
345    0xdf, 0x6e, 0xa4, 0x6d, 0x13, 0xb6, 0xbc, 0xaa, 0x8e, 0x44, 0x11, 0x50, 0x32, 0x91, 0x56, 0xa2,
346    0x22, 0x3f, 0x2f, 0x08, 0xbb, 0x4d, 0xbb, 0x69, 0xe6, 0xb1, 0xc2, 0x70, 0x79, 0x15, 0x54, 0xad,
347    0x4a, 0x29, 0xef, 0xa9, 0x3e, 0x64, 0x8d, 0xf1, 0x90, 0xf4, 0xa7, 0x93, 0x8c, 0x7a, 0x02, 0x4d,
348    0x38, 0x1f, 0x58, 0xb8, 0xe4, 0x7c, 0xe1, 0x66, 0x1c, 0x72, 0x30, 0xf3, 0x4c, 0xf4, 0x24, 0xd1,
349    0x2d, 0xb7, 0xf1, 0x5a, 0x0f, 0xb8, 0x20, 0xc5, 0x90, 0xe5, 0xca, 0x45, 0x84, 0x5c, 0x08, 0x08,
350    0xbf, 0xf9, 0x69, 0x41, 0xf5, 0x49, 0x85, 0x31, 0x35, 0x14, 0x69, 0x12, 0x57, 0x9c, 0xc8, 0xb7]);
351let g_dhPriData = new Uint8Array([
352    0x01, 0xbc, 0xa7, 0x42, 0x25, 0x79, 0xc5, 0xaf, 0x0f, 0x9c, 0xde, 0x00, 0x3b, 0x58, 0x5c, 0xd1,
353    0x1d, 0x7b, 0xcf, 0x66, 0xcd, 0xa9, 0x10, 0xae, 0x92, 0x2d, 0x3c, 0xb7, 0xf3]);
354let g_dhX509PubData = new Uint8Array([
355    0x30, 0x82, 0x02, 0x29, 0x30, 0x82, 0x01, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
356    0x01, 0x03, 0x01, 0x30, 0x82, 0x01, 0x0c, 0x02, 0x82, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff,
357    0xff, 0xff, 0xff, 0xff, 0xad, 0xf8, 0x54, 0x58, 0xa2, 0xbb, 0x4a, 0x9a, 0xaf, 0xdc, 0x56, 0x20,
358    0x27, 0x3d, 0x3c, 0xf1, 0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95, 0xa9, 0xe1, 0x36, 0x41,
359    0x14, 0x64, 0x33, 0xfb, 0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9, 0x7d, 0x2f, 0xe3, 0x63,
360    0x63, 0x0c, 0x75, 0xd8, 0xf6, 0x81, 0xb2, 0x02, 0xae, 0xc4, 0x61, 0x7a, 0xd3, 0xdf, 0x1e, 0xd5,
361    0xd5, 0xfd, 0x65, 0x61, 0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0, 0x85, 0x63, 0x65, 0x55,
362    0x3d, 0xed, 0x1a, 0xf3, 0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35, 0x98, 0x4f, 0x0c, 0x70,
363    0xe0, 0xe6, 0x8b, 0x77, 0xe2, 0xa6, 0x89, 0xda, 0xf3, 0xef, 0xe8, 0x72, 0x1d, 0xf1, 0x58, 0xa1,
364    0x36, 0xad, 0xe7, 0x35, 0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a, 0xbc, 0x0a, 0xb1, 0x82,
365    0xb3, 0x24, 0xfb, 0x61, 0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb, 0xb9, 0x6a, 0xda, 0xb7,
366    0x60, 0xd7, 0xf4, 0x68, 0x1d, 0x4f, 0x42, 0xa3, 0xde, 0x39, 0x4d, 0xf4, 0xae, 0x56, 0xed, 0xe7,
367    0x63, 0x72, 0xbb, 0x19, 0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70, 0x9e, 0x02, 0xfc, 0xe1,
368    0xcd, 0xf7, 0xe2, 0xec, 0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61, 0x91, 0x72, 0xfe, 0x9c,
369    0xe9, 0x85, 0x83, 0xff, 0x8e, 0x4f, 0x12, 0x32, 0xee, 0xf2, 0x81, 0x83, 0xc3, 0xfe, 0x3b, 0x1b,
370    0x4c, 0x6f, 0xad, 0x73, 0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05, 0xc5, 0x8e, 0xf1, 0x83,
371    0x7d, 0x16, 0x83, 0xb2, 0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa, 0x88, 0x6b, 0x42, 0x38,
372    0x61, 0x28, 0x5c, 0x97, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x02, 0x02,
373    0x02, 0x00, 0xe1, 0x03, 0x82, 0x01, 0x06, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0x8a, 0xbf, 0x16,
374    0x67, 0x1b, 0x92, 0x4b, 0xf2, 0xe0, 0x02, 0xc5, 0x1f, 0x84, 0x00, 0xf8, 0x93, 0x0f, 0x74, 0xe7,
375    0x0f, 0xba, 0x78, 0x30, 0xa8, 0x2d, 0x92, 0xef, 0x9b, 0x80, 0xeb, 0x76, 0xea, 0x26, 0x74, 0x72,
376    0x63, 0x6a, 0x27, 0xc3, 0x8f, 0xcf, 0xbe, 0x82, 0xa2, 0x8b, 0xdc, 0x65, 0x58, 0xe3, 0xff, 0x29,
377    0x97, 0xad, 0xb3, 0x4a, 0x2c, 0x50, 0x08, 0xb5, 0x68, 0xe1, 0x90, 0x5a, 0xdc, 0x48, 0xb3, 0x6b,
378    0x7a, 0xce, 0x2e, 0x81, 0x3d, 0x38, 0x35, 0x59, 0xdc, 0x39, 0x8a, 0x97, 0xfe, 0x20, 0x86, 0x20,
379    0xdb, 0x55, 0x38, 0x23, 0xca, 0xb5, 0x5b, 0x61, 0x00, 0xdc, 0x45, 0xe2, 0xa1, 0xf4, 0x1e, 0x7b,
380    0x01, 0x7a, 0x84, 0x36, 0xa4, 0xa8, 0x1c, 0x0d, 0x3d, 0xde, 0x57, 0x66, 0x73, 0x4e, 0xaf, 0xee,
381    0xb0, 0xb0, 0x69, 0x0c, 0x13, 0xba, 0x76, 0xff, 0x2e, 0xb6, 0x16, 0xf9, 0xfc, 0xd6, 0x09, 0x5b,
382    0xc7, 0x37, 0x65, 0x84, 0xd5, 0x82, 0x8a, 0xd7, 0x5b, 0x57, 0xe3, 0x0e, 0x89, 0xbe, 0x05, 0x05,
383    0x55, 0x2e, 0x9f, 0x94, 0x8a, 0x53, 0xdc, 0xb7, 0x00, 0xb2, 0x6a, 0x7b, 0x8e, 0xdf, 0x6e, 0xa4,
384    0x6d, 0x13, 0xb6, 0xbc, 0xaa, 0x8e, 0x44, 0x11, 0x50, 0x32, 0x91, 0x56, 0xa2, 0x22, 0x3f, 0x2f,
385    0x08, 0xbb, 0x4d, 0xbb, 0x69, 0xe6, 0xb1, 0xc2, 0x70, 0x79, 0x15, 0x54, 0xad, 0x4a, 0x29, 0xef,
386    0xa9, 0x3e, 0x64, 0x8d, 0xf1, 0x90, 0xf4, 0xa7, 0x93, 0x8c, 0x7a, 0x02, 0x4d, 0x38, 0x1f, 0x58,
387    0xb8, 0xe4, 0x7c, 0xe1, 0x66, 0x1c, 0x72, 0x30, 0xf3, 0x4c, 0xf4, 0x24, 0xd1, 0x2d, 0xb7, 0xf1,
388    0x5a, 0x0f, 0xb8, 0x20, 0xc5, 0x90, 0xe5, 0xca, 0x45, 0x84, 0x5c, 0x08, 0x08, 0xbf, 0xf9, 0x69,
389    0x41, 0xf5, 0x49, 0x85, 0x31, 0x35, 0x14, 0x69, 0x12, 0x57, 0x9c, 0xc8, 0xb7]);
390
391// X25519 key
392let g_x25519PubData = new Uint8Array([
393    0x9c, 0xf6, 0x7a, 0x8d, 0xce, 0xc2, 0x7f, 0xa7, 0xd9, 0xfd, 0xf1, 0xad, 0xac, 0xf0, 0xb3, 0x8c,
394    0xe8, 0x16, 0xa2, 0x65, 0xcc, 0x18, 0x55, 0x60, 0xcd, 0x2f, 0xf5, 0xe5, 0x72, 0xc9, 0x3c, 0x54]);
395// X25519 public key
396let g_x25519PriData = new Uint8Array([
397    0x20, 0xd5, 0xbb, 0x54, 0x6f, 0x1f, 0x00, 0x30, 0x4e, 0x33, 0x38, 0xb9, 0x8e, 0x6a, 0xdf, 0xad,
398    0x33, 0x6f, 0x51, 0x23, 0xff, 0x4d, 0x95, 0x26, 0xdc, 0xb0, 0x74, 0xb2, 0x5c, 0x7e, 0x85, 0x6c]);
399
400// RSA key
401let g_nData = new Uint8Array([
402    0xb6, 0xd8, 0x9b, 0x33, 0x78, 0xa2, 0x63, 0x21, 0x84, 0x47, 0xa1, 0x72, 0  x3d, 0x73, 0x10, 0xbd,
403    0xe9, 0x5d, 0x78, 0x44, 0x3d, 0x80, 0x18, 0x12, 0x60, 0xed, 0x29, 0x3e, 0xc7, 0x23, 0x0d, 0x3f,
404    0x02, 0x59, 0x28, 0xe2, 0x8f, 0x83, 0xdf, 0x37, 0x4b, 0x77, 0xce, 0x5f, 0xb6, 0xcd, 0x61, 0x72,
405    0xee, 0x01, 0xe2, 0x37, 0x4d, 0xfd, 0x4f, 0x39, 0xcf, 0xbd, 0xff, 0x84, 0x57, 0x44, 0xa5, 0x03]);
406let g_eData = new Uint8Array([0x01, 0x00, 0x01]);
407let g_dData = new Uint8Array([
408    0x35, 0x63, 0x89, 0xed, 0xbd, 0x8b, 0xac, 0xe6, 0x5c, 0x79, 0x8d, 0xea, 0x8d, 0x86, 0xcb, 0x9c,
409    0xa8, 0x47, 0x62, 0x96, 0x8a, 0x5e, 0x9c, 0xa8, 0xc1, 0x24, 0x7e, 0xa6, 0x95, 0xfe, 0xe6, 0x1e,
410    0xc0, 0xf3, 0x29, 0x76, 0xbb, 0x4d, 0xe4, 0xbc, 0x78, 0x64, 0xe1, 0x79, 0xcd, 0x8a, 0x45, 0xac,
411    0x5c, 0x88, 0xea, 0xb4, 0x10, 0xd8, 0x90, 0x65, 0x7b, 0x94, 0xe8, 0x87, 0x30, 0x2a, 0x04, 0x01]);
412let g_pubData = new Uint8Array([
413    0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
414    0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0x9e, 0x93, 0x57, 0xc4, 0xab, 0xde, 0x30,
415    0xc5, 0x3f, 0x3b, 0x33, 0xa6, 0xdc, 0x4a, 0xdb, 0xbf, 0x12, 0x9e, 0x5d, 0xc4, 0xba, 0x0e, 0x15,
416    0x06, 0x41, 0xd8, 0x96, 0x43, 0xca, 0xc5, 0xea, 0x9f, 0xdd, 0xa0, 0x2a, 0xf1, 0x53, 0x46, 0x14,
417    0x36, 0x7a, 0xab, 0xbc, 0x92, 0x1b, 0x07, 0xc6, 0x9a, 0x7d, 0x0c, 0xd0, 0xa0, 0x0f, 0x31, 0xd5,
418    0x38, 0x84, 0x6c, 0x08, 0xcb, 0x9b, 0x10, 0xa6, 0x4d, 0x02, 0x03, 0x01, 0x00, 0x01]);
419
420// ECC key
421let g_eccXData = new Uint8Array([
422    0xa5, 0xb8, 0xa3, 0x78, 0x1d, 0x6d, 0x76, 0xe0, 0xb3, 0xf5, 0x6f, 0x43, 0x9d, 0xcf, 0x60, 0xf6,
423    0x0b, 0x3f, 0x64, 0x45, 0xa8, 0x3f, 0x1a, 0x96, 0xf1, 0xa1, 0xa4, 0x5d, 0x3e, 0x2c, 0x3f, 0x13]);
424let g_eccYData = new Uint8Array([
425    0xd7, 0x81, 0xf7, 0x2a, 0xb5, 0x8d, 0x19, 0x3d, 0x9b, 0x96, 0xc7, 0x6a, 0x10, 0xf0, 0xaa, 0xbc,
426    0x91, 0x6f, 0x4d, 0xa7, 0x09, 0xb3, 0x57, 0x88, 0x19, 0x6f, 0x00, 0x4b, 0xad, 0xee, 0x34, 0x35]);
427let g_eccZData = new Uint8Array([
428    0xfb, 0x8b, 0x9f, 0x12, 0xa0, 0x83, 0x19, 0xbe, 0x6a, 0x6f, 0x63, 0x2a, 0x7c, 0x86, 0xba, 0xca,
429    0x64, 0x0b, 0x88, 0x96, 0xe2, 0xfa, 0x77, 0xbc, 0x71, 0xe3, 0x0f, 0x0f, 0x9e, 0x3c, 0xe5, 0xf9]);
430let g_eccPubData = new Uint8Array([
431    0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
432    0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xa5, 0xb8, 0xa3, 0x78, 0x1d,
433    0x6d, 0x76, 0xe0, 0xb3, 0xf5, 0x6f, 0x43, 0x9d, 0xcf, 0x60, 0xf6, 0x0b, 0x3f, 0x64, 0x45, 0xa8,
434    0x3f, 0x1a, 0x96, 0xf1, 0xa1, 0xa4, 0x5d, 0x3e, 0x2c, 0x3f, 0x13, 0xd7, 0x81, 0xf7, 0x2a, 0xb5,
435    0x8d, 0x19, 0x3d, 0x9b, 0x96, 0xc7, 0x6a, 0x10, 0xf0, 0xaa, 0xbc, 0x91, 0x6f, 0x4d, 0xa7, 0x09,
436    0xb3, 0x57, 0x88, 0x19, 0x6f, 0x00, 0x4b, 0xad, 0xee, 0x34, 0x35]);
437
438// Import the DH2048 key.
439async function ImportDhTest(alg, keyType) {
440    let importKeyAlias = 'import_dh_key';
441    let properties = new Array();
442    properties[0] = {
443        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
444        value: huks.HuksKeyAlg.HUKS_ALG_DH
445    }
446    properties[1] = {
447        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
448        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE
449    }
450    properties[2] = {
451        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
452        value: huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048
453    }
454    properties[3] = {
455        tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE,
456        value: huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY
457    }
458    properties[4] = {
459        tag: huks.HuksTag.HUKS_TAG_DIGEST,
460        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
461    }
462    let huksOptions = {
463        properties: properties,
464        inData: new Uint8Array(new Array())
465    }
466    huksOptions.properties[0].value = alg;
467    huksOptions.properties[3].value = keyType;
468
469    // Compare the key types.
470    if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) {
471        /* Concatenate the huksOptions.inData field with a non-public key in the following format:
472         * keyAlg type (4 bytes) + key_dh length (4 bytes) +
473         * g_dhPubData length (4 bytes) + g_dhPriData length (4 bytes) +
474         * Reserved size (4 bytes) + g_dhPubData + g_dhPriData
475         */
476        // Key pair
477        let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_DH, huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048, g_dhPubData.length, g_dhPriData.length, 0]);
478        let u8Material = Uint32ToUint8(Material);
479        let strMaterial = Uint8ArrayToString(u8Material);
480
481        let strXData = strMaterial.concat(Uint8ArrayToString(g_dhPubData));
482        let strData = strXData.concat(Uint8ArrayToString(g_dhPriData));
483        huksOptions.inData = StringToUint8Array(strData);
484    } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) {
485        // Private key
486        let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_DH, huks.HuksKeySize.HUKS_DH_KEY_SIZE_2048, 0, g_dhPriData.length, 0]);
487        let u8Material = Uint32ToUint8(Material);
488        let strMaterial = Uint8ArrayToString(u8Material);
489
490        let strData = strMaterial.concat(Uint8ArrayToString(g_dhPriData));
491        huksOptions.inData = StringToUint8Array(strData);
492    } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) {
493        // Public key
494        huksOptions.inData = g_dhX509PubData;
495    }
496
497    await publicImportKeyFunc(importKeyAlias, huksOptions);
498    await publicDeleteKeyFunc(importKeyAlias, huksOptions);
499}
500
501// Import the ECC256 key.
502async function ImportEccTest(alg, keyType) {
503    let importKeyAlias = 'import_ecc_key';
504    let properties = new Array();
505    properties[0] = {
506        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
507        value: huks.HuksKeyAlg.HUKS_ALG_ECC
508    }
509    properties[1] = {
510        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
511        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE
512    }
513    properties[2] = {
514        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
515        value: huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256
516    }
517    properties[3] = {
518        tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE,
519        value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR
520    }
521    properties[4] = {
522        tag: huks.HuksTag.HUKS_TAG_DIGEST,
523        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
524    }
525    let huksOptions = {
526        properties: properties,
527        inData: new Uint8Array(new Array())
528    }
529    huksOptions.properties[0].value = alg;
530    huksOptions.properties[3].value = keyType;
531
532    // Compare the key types.
533    if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) {
534        /* Concatenate the huksOptions.inData field with a non-public key in the following format:
535         * keyAlg type (4 bytes) + key_ecc length (4 bytes) +
536         * g_eccXData length (4 bytes) + g_eccYData length (4 bytes) +
537         * g_eccZData length (4 bytes) + g_eccXData +
538         * g_eccYData + g_eccZData
539         */
540        // Key pair
541        let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_ECC, huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256, g_eccXData.length, g_eccYData.length, g_eccZData.length]);
542        let u8Material = Uint32ToUint8(Material);
543        let strMaterial = Uint8ArrayToString(u8Material);
544
545        let strXData = strMaterial.concat(Uint8ArrayToString(g_eccXData));
546        let strYData = strXData.concat(Uint8ArrayToString(g_eccYData));
547        let strData = strYData.concat(Uint8ArrayToString(g_eccZData));
548        huksOptions.inData = StringToUint8Array(strData);
549    } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) {
550        // Private key
551        huksOptions.properties[3].value == huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY
552        let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_ECC, huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256, 0, 0, g_eccZData.length]);
553        let u8Material = Uint32ToUint8(Material);
554        let strMaterial = Uint8ArrayToString(u8Material);
555
556        let strData = strMaterial.concat(Uint8ArrayToString(g_eccZData));
557        huksOptions.inData = StringToUint8Array(strData);
558    } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) {
559        // Public key
560        huksOptions.inData = g_eccPubData;
561    }
562
563    await publicImportKeyFunc(importKeyAlias, huksOptions);
564    await publicDeleteKeyFunc(importKeyAlias, huksOptions);
565}
566
567// Import the RSA512 key.
568async function ImportRsaTest(alg, keyType) {
569    let importKeyAlias = 'import_rsa_key';
570    let properties = new Array();
571    properties[0] = {
572        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
573        value: huks.HuksKeyAlg.HUKS_ALG_RSA
574    }
575    properties[1] = {
576        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
577        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN
578    }
579    properties[2] = {
580        tag: huks.HuksTag.HUKS_TAG_DIGEST,
581        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
582    }
583    properties[3] = {
584        tag: huks.HuksTag.HUKS_TAG_PADDING,
585        value: huks.HuksKeyPadding.HUKS_PADDING_PSS
586    }
587    properties[4] = {
588        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
589        value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512
590    }
591    properties[5] = {
592        tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE,
593        value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR
594    }
595    let huksOptions = {
596        properties: properties,
597        inData: new Uint8Array(new Array())
598    }
599    huksOptions.properties[0].value = alg;
600    huksOptions.properties[3].value = keyType;
601
602    // Compare the key types.
603    if (huksOptions.properties[5].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) {
604        /* Concatenate the huksOptions.inData field with a non-public key in the following format:
605         * keyAlg type (4 bytes) + key_rsa length (4 bytes) +
606         * g_nData length (4 bytes) + g_eData length (4 bytes) +
607         * g_dData length (4 bytes) + g_nData +
608         * g_eData + g_dData
609         */
610        // Key pair
611        let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_RSA, huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512, g_nData.length, g_eData.length, g_dData.length]);
612        let u8Material = Uint32ToUint8(Material);
613        let strMaterial = Uint8ArrayToString(u8Material);
614        let strNData = strMaterial.concat(Uint8ArrayToString(g_nData));
615        let strEData = strNData.concat(Uint8ArrayToString(g_eData));
616        let strData = strEData.concat(Uint8ArrayToString(g_dData));
617        huksOptions.inData = StringToUint8Array(strData);
618    } else if (huksOptions.properties[5].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) {
619        // Private key
620        let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_RSA, huks.HuksKeySize.HUKS_RSA_KEY_SIZE_512, g_nData.length, 0, g_dData.length]);
621        let u8Material = Uint32ToUint8(Material);
622        let strMaterial = Uint8ArrayToString(u8Material);
623        let strNData = strMaterial.concat(Uint8ArrayToString(g_nData));
624        let strData = strNData.concat(Uint8ArrayToString(g_dData));
625        huksOptions.inData = StringToUint8Array(strData);
626    } else if (huksOptions.properties[5].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) {
627        // Public key
628        huksOptions.inData = g_pubData;
629    }
630    await publicImportKeyFunc(importKeyAlias, huksOptions);
631    await publicDeleteKeyFunc(importKeyAlias, huksOptions);
632}
633
634// Import the X25519 key.
635async function ImportX25519Test(alg, keyType) {
636    let importKeyAlias = 'import_x25519_key';
637    let properties = new Array();
638    properties[0] = {
639        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
640        value: huks.HuksKeyAlg.HUKS_ALG_X25519
641    }
642    properties[1] = {
643        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
644        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE
645    }
646    properties[2] = {
647        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
648        value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256
649    }
650    properties[3] = {
651        tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE,
652        value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR
653    }
654    properties[4] = {
655        tag: huks.HuksTag.HUKS_TAG_DIGEST,
656        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
657    }
658    let huksOptions = {
659        properties: properties,
660        inData: new Uint8Array(new Array())
661    }
662    huksOptions.properties[0].value = alg;
663    huksOptions.properties[3].value = keyType;
664
665    // Compare the key types.
666    if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR) {
667        /* Concatenate the huksOptions.inData field with a non-public key in the following format:
668         * keyAlg type (4 bytes) + key_x25519 length (4 bytes) +
669         * g_x25519PubData length (4) + g_x25519PriData length (4) +
670         * Reserved size (4 bytes) + g_x25519PubData +
671         * g_x25519PriData
672         */
673        // Key pair
674        let Material = new Uint32Array([huks.HuksKeyAlg.HUKS_ALG_X25519, huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256, g_x25519PriData.length, g_x25519PubData.length, 0]);
675        let u8Material = Uint32ToUint8(Material);
676        let strMaterial = Uint8ArrayToString(u8Material);
677        let strXData = strMaterial.concat(Uint8ArrayToString(g_x25519PubData));
678        let strData = strXData.concat(Uint8ArrayToString(g_x25519PriData));
679        huksOptions.inData = StringToUint8Array(strData);
680    } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY) {
681        // Private key
682        huksOptions.inData = g_x25519PriData;
683    } else if (huksOptions.properties[3].value === huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY) {
684        // Public key
685        huksOptions.inData = g_x25519PubData;
686    }
687    await publicImportKeyFunc(importKeyAlias, huksOptions);
688    await publicDeleteKeyFunc(importKeyAlias, huksOptions);
689}
690
691@Entry
692@Component
693struct Index {
694    build() {
695        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
696            Button() {
697                Text('testExportRsa')
698                    .fontSize(30)
699                    .fontWeight(FontWeight.Bold)
700                }.type(ButtonType.Capsule)
701            .margin({
702                top: 20
703            })
704            .backgroundColor('#0D9FFB')
705            .onClick(() => {
706                testExportRsa();
707            })
708
709            Button() {
710                Text('testImportDh')
711                    .fontSize(30)
712                    .fontWeight(FontWeight.Bold)
713            }.type(ButtonType.Capsule)
714            .margin({
715                top: 20
716            })
717            .backgroundColor('#0D9FFB')
718            .onClick(() => {
719                ImportDhTest(huks.HuksKeyAlg.HUKS_ALG_DH, huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY);
720            })
721
722            Button() {
723                Text('testImportRsa')
724                    .fontSize(30)
725                    .fontWeight(FontWeight.Bold)
726            }.type(ButtonType.Capsule)
727            .margin({
728                top: 20
729            })
730            .backgroundColor('#0D9FFB')
731            .onClick(() => {
732                ImportRsaTest(huks.HuksKeyAlg.HUKS_ALG_RSA, huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR);
733            })
734
735            Button() {
736                Text('testImportX25519')
737                    .fontSize(30)
738                    .fontWeight(FontWeight.Bold)
739            }.type(ButtonType.Capsule)
740            .margin({
741                top: 20
742            })
743            .backgroundColor('#0D9FFB')
744            .onClick(() => {
745                ImportX25519Test(huks.HuksKeyAlg.HUKS_ALG_X25519, huks.HuksImportKeyType.HUKS_KEY_TYPE_PRIVATE_KEY);
746            })
747
748            Button() {
749                Text('testImportEcc')
750                    .fontSize(30)
751                    .fontWeight(FontWeight.Bold)
752            }.type(ButtonType.Capsule)
753            .margin({
754                top: 20
755            })
756            .backgroundColor('#0D9FFB')
757            .onClick(() => {
758                ImportEccTest(huks.HuksKeyAlg.HUKS_ALG_ECC, huks.HuksImportKeyType.HUKS_KEY_TYPE_PUBLIC_KEY);
759            })
760        }
761        .width('100%')
762        .height('100%')
763    }
764}
765```
766
767### Secure Key Import
768
769The service invoker and HUKS negotiate a shared symmetric key to encrypt and decrypt the intermediate key and the key to be imported. After the encrypted key is imported, it is decrypted and saved in HUKS. The keys in plaintext can be processed in HUKS only.
770
771The development procedure is as follows:
772
7731.   Generate a key pair in HUKS. The key pair is used to encrypt the key to import.
7742.  Export the public key of the key pair and obtain a shared secret through key agreement.
7753.  Generate intermediate key materials to encrypt the key.
7764.  Import the key.
777
778**Supported Key Types**
779
780AES128, AES192, AES256, RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, HmacSHA512, ECC224, ECC256, ECC384, ECC521, Curve25519, DSA, SM2, SM3, SM4
781
782> **NOTICE**
783>
784> - When generating a public key, set **HUKS_TAG_PURPOSE = HUKS_KEY_PURPOSE_UNWRAP**.
785> - Set **HUKS_TAG_IMPORT_KEY_TYPE = HUKS_KEY_TYPE_KEY_PAIR**.
786> - When importing a key in secure mode, add **HUKS_TAG_UNWRAP_ALGORITHM_SUITE** with value set to **HUKS_UNWRAP_SUITE_X25519_AES_256_GCM_NOPADDING** or **HUKS_UNWRAP_SUITE_ECDH_AES_256_GCM_NOPADDING**.
787> - The key alias cannot exceed 64 bytes.
788
789Before you get started, understand the following variables:
790
791| Parameter        | Type       | Mandatory| Description                            |
792| -------------- | ----------- | ---- | -------------------------------- |
793| importAlias    | string      | Yes  | Alias of the key to import.                      |
794| wrapAlias      | string      | Yes  | Alias of the key.                      |
795| genWrapOptions | HuksOptions | Yes  | Tags required for generating the key.|
796| importOptions  | HuksOptions | Yes  | Tags required for importing the encrypted key.    |
797
798For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
799
800**Example**
801
802```ts
803import huks from '@ohos.security.huks';
804
805async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
806    console.info(`enter callback export`);
807    try {
808        await exportKeyItem(keyAlias, huksOptions)
809            .then ((data) => {
810                console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`);
811                if (data.outData !== null) {
812                    exportKey = data.outData;
813                }
814            })
815            .catch(error => {
816                console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`);
817            });
818    } catch (error) {
819        console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
820    }
821}
822
823function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
824    return new Promise((resolve, reject) => {
825        try {
826            huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
827                if (error) {
828                    reject(error);
829                } else {
830                    resolve(data);
831                }
832            });
833        } catch (error) {
834            throw(error);
835        }
836    });
837}
838
839async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
840    console.info(`enter promise importKeyItem`);
841    try {
842        await importKeyItem(keyAlias, huksOptions)
843            .then ((data) => {
844                console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`);
845            })
846            .catch(error => {
847                console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`);
848            });
849    } catch (error) {
850        console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
851    }
852}
853
854function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
855    return new Promise((resolve, reject) => {
856        try {
857            huks.importKeyItem(keyAlias, huksOptions, function (error, data) {
858                if (error) {
859                    reject(error);
860                } else {
861                    resolve(data);
862                }
863            });
864        } catch (error) {
865            throw(error);
866        }
867    });
868}
869
870async function publicImportWrappedKey(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions) {
871    console.info(`enter callback importWrappedKeyItem`);
872    try {
873        await importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions)
874            .then ((data) => {
875                console.info(`callback: importWrappedKeyItem success, data = ${JSON.stringify(data)}`);
876            })
877            .catch(error => {
878                console.error(`callback: importWrappedKeyItem failed, code: ${error.code}, msg: ${error.message}`);
879            });
880    } catch (error) {
881        console.error(`callback: importWrappedKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
882    }
883}
884
885function importWrappedKeyItem(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions) {
886    return new Promise((resolve, reject) => {
887        try {
888            huks.importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions, function (error, data) {
889                if (error) {
890                    reject(error);
891                } else {
892                    resolve(data);
893                }
894            });
895        } catch (error) {
896            throw(error);
897        }
898    });
899}
900
901async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
902    console.info(`enter callback deleteKeyItem`);
903    try {
904        await deleteKeyItem(keyAlias, huksOptions)
905            .then ((data) => {
906                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
907            })
908            .catch(error => {
909                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
910            });
911    } catch (error) {
912        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
913    }
914}
915
916function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
917    return new Promise((resolve, reject) => {
918        try {
919            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
920                if (error) {
921                    reject(error);
922                } else {
923                    resolve(data);
924                }
925            });
926        } catch (error) {
927            throw(error);
928        }
929    });
930}
931
932let importAlias = "importAlias";
933let wrapAlias = "wrappingKeyAlias";
934let exportKey;
935
936let inputEccPair = new Uint8Array([
937    0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
938    0x20, 0x00, 0x00, 0x00, 0xa5, 0xb8, 0xa3, 0x78, 0x1d, 0x6d, 0x76, 0xe0, 0xb3, 0xf5, 0x6f, 0x43,
939    0x9d, 0xcf, 0x60, 0xf6, 0x0b, 0x3f, 0x64, 0x45, 0xa8, 0x3f, 0x1a, 0x96, 0xf1, 0xa1, 0xa4, 0x5d,
940    0x3e, 0x2c, 0x3f, 0x13, 0xd7, 0x81, 0xf7, 0x2a, 0xb5, 0x8d, 0x19, 0x3d, 0x9b, 0x96, 0xc7, 0x6a,
941    0x10, 0xf0, 0xaa, 0xbc, 0x91, 0x6f, 0x4d, 0xa7, 0x09, 0xb3, 0x57, 0x88, 0x19, 0x6f, 0x00, 0x4b,
942    0xad, 0xee, 0x34, 0x35, 0xfb, 0x8b, 0x9f, 0x12, 0xa0, 0x83, 0x19, 0xbe, 0x6a, 0x6f, 0x63, 0x2a,
943    0x7c, 0x86, 0xba, 0xca, 0x64, 0x0b, 0x88, 0x96, 0xe2, 0xfa, 0x77, 0xbc, 0x71, 0xe3, 0x0f, 0x0f,
944    0x9e, 0x3c, 0xe5, 0xf9]);
945
946let properties = new Array();
947properties[0] = {
948    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
949    value: huks.HuksKeyAlg.HUKS_ALG_ECC
950};
951properties[1] = {
952    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
953    value: huks.HuksKeySize.HUKS_ECC_KEY_SIZE_256
954};
955properties[2] = {
956    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
957    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_UNWRAP
958};
959properties[3] = {
960    tag: huks.HuksTag.HUKS_TAG_DIGEST,
961    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
962};
963properties[4] = {
964    tag: huks.HuksTag.HUKS_TAG_IMPORT_KEY_TYPE,
965    value: huks.HuksImportKeyType.HUKS_KEY_TYPE_KEY_PAIR,
966};
967let huksOptions = {
968    properties: properties,
969    inData: inputEccPair
970};
971
972let importProperties = new Array();
973importProperties[0] = {
974    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
975    value: huks.HuksKeyAlg.HUKS_ALG_AES
976};
977importProperties[1] = {
978    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
979    value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256
980};
981importProperties[2] = {
982    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
983    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
984};
985importProperties[3] = {
986    tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
987    value: huks.HuksCipherMode.HUKS_MODE_CBC
988};
989importProperties[4] = {
990    tag: huks.HuksTag.HUKS_TAG_PADDING,
991    value: huks.HuksKeyPadding.HUKS_PADDING_NONE
992};
993importProperties[5] = {
994    tag: huks.HuksTag.HUKS_TAG_UNWRAP_ALGORITHM_SUITE,
995    value: huks.HuksUnwrapSuite.HUKS_UNWRAP_SUITE_ECDH_AES_256_GCM_NOPADDING
996};
997let importOptions = {
998    properties: importProperties,
999    inData: new Uint8Array(new Array())
1000};
1001
1002async function importWrappedKeyItemTest() {
1003
1004    console.info(`enter ImportWrapKey test`);
1005    await publicImportKeyFunc(wrapAlias, huksOptions);
1006
1007    await publicExportKeyFunc(wrapAlias, huksOptions);
1008
1009    /* The following operation does not involve calling of HUKS APIs, and the specific implementation is not provided here.
1010     * For example, import keyA.
1011     * 1. Use ECC to generate a public and private key pair named keyB. The public key is keyB_pub, and the private key is keyB_pri.
1012     * 2. Use keyB_pri and the public key obtained from wrappingAlias to negotiate the shared key share_key.
1013     * 3. Randomly generate a key kek to encrypt keyA using AES-GCM. During the encryption, record nonce1, aad1, ciphertext keyA_enc, and encrypted tag1.
1014     * 4. Use share_key to encrypt kek using AES-GCM. During the encryption, record nonce2, aad2, ciphertext kek_enc, and encrypted tag2.
1015     * 5. Generate the **importOptions.inData** field in the following format:
1016     * keyB_pub length (4 bytes) + keyB_pub + aad2 length (4 bytes) + aad2 +
1017     * nonce2 length (4 bytes) + nonce2 + tag2 length (4 bytes) + tag2 +
1018     * kek_enc length (4 bytes) + kek_enc + aad1 length (4 bytes) + aad1 +
1019     * nonce1 length (4 bytes) + nonce1 + tag1 length (4 bytes) + tag1 +
1020     * Memory occupied by the keyA length (4 bytes) + keyA length + keyA_enc length (4 bytes) + keyA_enc
1021     */
1022    let inputKey = new Uint8Array([
1023        0x5b, 0x00, 0x00, 0x00, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
1024        0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xc0,
1025        0xfe, 0x1c, 0x67, 0xde, 0x86, 0x0e, 0xfb, 0xaf, 0xb5, 0x85, 0x52, 0xb4, 0x0e, 0x1f, 0x6c, 0x6c,
1026        0xaa, 0xc5, 0xd9, 0xd2, 0x4d, 0xb0, 0x8a, 0x72, 0x24, 0xa1, 0x99, 0xaf, 0xfc, 0x3e, 0x55, 0x5a,
1027        0xac, 0x99, 0x3d, 0xe8, 0x34, 0x72, 0xb9, 0x47, 0x9c, 0xa6, 0xd8, 0xfb, 0x00, 0xa0, 0x1f, 0x9f,
1028        0x7a, 0x41, 0xe5, 0x44, 0x3e, 0xb2, 0x76, 0x08, 0xa2, 0xbd, 0xe9, 0x41, 0xd5, 0x2b, 0x9e, 0x10,
1029        0x00, 0x00, 0x00, 0xbf, 0xf9, 0x69, 0x41, 0xf5, 0x49, 0x85, 0x31, 0x35, 0x14, 0x69, 0x12, 0x57,
1030        0x9c, 0xc8, 0xb7, 0x10, 0x00, 0x00, 0x00, 0x2d, 0xb7, 0xf1, 0x5a, 0x0f, 0xb8, 0x20, 0xc5, 0x90,
1031        0xe5, 0xca, 0x45, 0x84, 0x5c, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x43, 0x25, 0x1b, 0x2f, 0x5b,
1032        0x86, 0xd8, 0x87, 0x04, 0x4d, 0x38, 0xc2, 0x65, 0xcc, 0x9e, 0xb7, 0x20, 0x00, 0x00, 0x00, 0xf4,
1033        0xe8, 0x93, 0x28, 0x0c, 0xfa, 0x4e, 0x11, 0x6b, 0xe8, 0xbd, 0xa8, 0xe9, 0x3f, 0xa7, 0x8f, 0x2f,
1034        0xe3, 0xb3, 0xbf, 0xaf, 0xce, 0xe5, 0x06, 0x2d, 0xe6, 0x45, 0x5d, 0x19, 0x26, 0x09, 0xe7, 0x10,
1035        0x00, 0x00, 0x00, 0xf4, 0x1e, 0x7b, 0x01, 0x7a, 0x84, 0x36, 0xa4, 0xa8, 0x1c, 0x0d, 0x3d, 0xde,
1036        0x57, 0x66, 0x73, 0x10, 0x00, 0x00, 0x00, 0xe3, 0xff, 0x29, 0x97, 0xad, 0xb3, 0x4a, 0x2c, 0x50,
1037        0x08, 0xb5, 0x68, 0xe1, 0x90, 0x5a, 0xdc, 0x10, 0x00, 0x00, 0x00, 0x26, 0xae, 0xdc, 0x4e, 0xa5,
1038        0x6e, 0xb1, 0x38, 0x14, 0x24, 0x47, 0x1c, 0x41, 0x89, 0x63, 0x11, 0x04, 0x00, 0x00, 0x00, 0x20,
1039        0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0b, 0xcb, 0xa9, 0xa8, 0x5f, 0x5a, 0x9d, 0xbf, 0xa1,
1040        0xfc, 0x72, 0x74, 0x87, 0x79, 0xf2, 0xf4, 0x22, 0x0c, 0x8a, 0x4d, 0xd8, 0x7e, 0x10, 0xc8, 0x44,
1041        0x17, 0x95, 0xab, 0x3b, 0xd2, 0x8f, 0x0a
1042    ]);
1043
1044    importOptions.inData = inputKey;
1045    await publicImportWrappedKey(importAlias, wrapAlias, importOptions);
1046
1047    await publicDeleteKeyFunc(wrapAlias, huksOptions);
1048    await publicDeleteKeyFunc(importAlias, importOptions);
1049}
1050
1051@Entry
1052@Component
1053struct Index {
1054    build() {
1055        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
1056            Button() {
1057                Text('importWrappedKeyItemTest')
1058                    .fontSize(30)
1059                    .fontWeight(FontWeight.Bold)
1060            }.type(ButtonType.Capsule)
1061            .margin({
1062                top: 20
1063            })
1064            .backgroundColor('#0D9FFB')
1065            .onClick(()=>{
1066                importWrappedKeyItemTest();
1067            })
1068        }
1069        .width('100%')
1070        .height('100%')
1071    }
1072}
1073```
1074
1075### Key Encryption and Decryption
1076
1077Use the symmetric or asymmetric key stored in HUKS to encrypt or decrypt data based on the specified alias. The keys in plaintext must be in a secure environment during the encryption and decryption process.
1078
1079The development procedure is as follows:
1080
10811. Generate a key.
10822. Encrypt the key.
10833. Decrypt the key.
1084
1085**Supported key types**:
1086
1087| HUKS_ALG_ALGORITHM                                           | HUKS_TAG_PURPOSE                                   | HUKS_TAG_DIGEST                                              | HUKS_TAG_PADDING                                             | HUKS_TAG_BLOCK_MODE                         | HUKS_TAG_IV |
1088| ------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------- | ----------- |
1089| HUKS_ALG_SM4 (supported key length: HUKS_SM4_KEY_SIZE_128)| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| Optional                                                  | HUKS_PADDING_NONE                                            | HUKS_MODE_CTR  HUKS_MODE_ECB  HUKS_MODE_CBC | Mandatory   |
1090| HUKS_ALG_SM4 (supported key length: HUKS_SM4_KEY_SIZE_128)| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| Optional                                                  | HUKS_PADDING_PKCS7                                           | HUKS_MODE_ECB  HUKS_MODE_CBC                | Mandatory   |
1091| HUKS_ALG_RSA (supported lengths: HUKS_RSA_KEY_SIZE_512, HUKS_RSA_KEY_SIZE_768, HUKS_RSA_KEY_SIZE_1024, HUKS_RSA_KEY_SIZE_2048, HUKS_RSA_KEY_SIZE_3072, HUKS_RSA_KEY_SIZE_4096)| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_DIGEST_SHA1 HUKS_DIGEST_SHA224  HUKS_DIGEST_SHA256  HUKS_DIGEST_SHA384  HUKS_DIGEST_SHA512 | HUKS_PADDING_NONE  HUKS_PADDING_PKCS1_V1_5  HUKS_PADDING_OAEP | HUKS_MODE_ECB                               | Optional |
1092
1093| HUKS_ALG_ALGORITHM                                           | HUKS_TAG_PURPOSE         | HUKS_TAG_PADDING                      | HUKS_TAG_BLOCK_MODE          | HUKS_TAG_IV | HUKS_TAG_NONCE | HUKS_TAG_ASSOCIATED_DATA | HUKS_TAG_AE_TAG |
1094| ------------------------------------------------------------ | ------------------------ | ------------------------------------- | ---------------------------- | ----------- | -------------- | ------------------------ | --------------- |
1095| HUKS_ALG_AES (supported key lengths: HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256)| HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| HUKS_MODE_CBC                | Mandatory   | Optional    | Optional              | Optional     |
1096| HUKS_ALG_AES                                                 | HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_NONE                     | HUKS_MODE_CCM  HUKS_MODE_GCM | Optional | Mandatory      | Mandatory                | Optional     |
1097| HUKS_ALG_AES                                                 | HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_NONE                     | HUKS_MODE_CTR                | Mandatory   | Optional    | Optional              | Optional     |
1098| HUKS_ALG_AES                                                 | HUKS_KEY_PURPOSE_ENCRYPT | HUKS_PADDING_PKCS7  HUKS_PADDING_NONE | HUKS_MODE_ECB                | Mandatory   | Optional    | Optional              | Optional     |
1099| HUKS_ALG_AES                                                 | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| HUKS_MODE_CBC                | Mandatory   | Optional    | Optional              | Mandatory       |
1100| HUKS_ALG_AES                                                 | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE                     | HUKS_MODE_CCM  HUKS_MODE_GCM | Optional | Mandatory      | Mandatory                | Optional     |
1101| HUKS_ALG_AES                                                 | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE                     | HUKS_MODE_CTR                | Mandatory   | Optional    | Optional              | Optional     |
1102| HUKS_ALG_AES                                                 | HUKS_KEY_PURPOSE_DECRYPT | HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| HUKS_MODE_ECB                | Mandatory   | Optional    | Optional              | Optional     |
1103
1104> **NOTE**<br>
1105>
1106> The key alias cannot exceed 64 bytes.
1107
1108Before you get started, understand the following variables:
1109
1110| Parameter        | Type       | Mandatory| Description                    |
1111| -------------- | ----------- | ---- | ------------------------ |
1112| srcKeyAlias    | string      | Yes  | Alias of the key.              |
1113| huksOptions    | HuksOptions | Yes  | Tags required for generating the key.|
1114| encryptOptions | HuksOptions | Yes  | Tags required for encrypting the key.|
1115| decryptOptions | HuksOptions | Yes  | Tags required for decrypting the key.|
1116
1117For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
1118
1119**Example 1:**
1120
1121```ts
1122/* The cipher operation supports RSA, AES, and SM4 keys.
1123 *
1124 * The following uses the Promise() operation of an SM4 128-bit key as an example.
1125 */
1126import huks from '@ohos.security.huks';
1127
1128function StringToUint8Array(str) {
1129    let arr = [];
1130    for (let i = 0, j = str.length; i < j; ++i) {
1131        arr.push(str.charCodeAt(i));
1132    }
1133    return new Uint8Array(arr);
1134}
1135
1136function Uint8ArrayToString(fileData) {
1137    let dataString = '';
1138    for (let i = 0; i < fileData.length; i++) {
1139        dataString += String.fromCharCode(fileData[i]);
1140    }
1141    return dataString;
1142}
1143
1144async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1145    console.info(`enter callback generateKeyItem`);
1146    try {
1147        await generateKeyItem(keyAlias, huksOptions)
1148            .then((data) => {
1149                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
1150            })
1151            .catch(error => {
1152                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
1153            });
1154    } catch (error) {
1155        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
1156    }
1157}
1158
1159function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
1160    return new Promise((resolve, reject) => {
1161        try {
1162            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
1163                if (error) {
1164                    reject(error);
1165                } else {
1166                    resolve(data);
1167                }
1168            });
1169        } catch (error) {
1170            throw(error);
1171        }
1172    });
1173}
1174
1175async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1176    console.info(`enter promise doInit`);
1177    try {
1178        await huks.initSession(keyAlias, huksOptions)
1179            .then ((data) => {
1180                console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
1181                handle = data.handle;
1182            })
1183            .catch(error => {
1184                console.error(`promise: doInit key failed, code: ${error.code}, msg: ${error.message}`);
1185            });
1186    } catch (error) {
1187        console.error(`promise: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
1188    }
1189}
1190
1191async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
1192    console.info(`enter callback doUpdate`);
1193    try {
1194        await updateSession(handle, huksOptions)
1195            .then ((data) => {
1196                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
1197                updateResult = Array.from(data.outData);
1198            })
1199            .catch(error => {
1200                console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
1201            });
1202    } catch (error) {
1203        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
1204    }
1205}
1206
1207function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
1208    return new Promise((resolve, reject) => {
1209        try {
1210            huks.updateSession(handle, huksOptions, function (error, data) {
1211                if (error) {
1212                    reject(error);
1213                } else {
1214                    resolve(data);
1215                }
1216            });
1217        } catch (error) {
1218            throw(error);
1219        }
1220    });
1221}
1222
1223async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
1224    console.info(`enter callback doFinish`);
1225    try {
1226        await finishSession(handle, huksOptions)
1227            .then ((data) => {
1228                finishOutData = Uint8ArrayToString(new Uint8Array(updateResult));
1229                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
1230            })
1231            .catch(error => {
1232                console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
1233            });
1234    } catch (error) {
1235        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
1236    }
1237}
1238
1239function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
1240    return new Promise((resolve, reject) => {
1241        try {
1242            huks.finishSession(handle, huksOptions, function (error, data) {
1243                if (error) {
1244                    reject(error);
1245                } else {
1246                    resolve(data);
1247                }
1248            });
1249        } catch (error) {
1250            throw(error);
1251        }
1252    });
1253}
1254
1255async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1256    console.info(`enter callback deleteKeyItem`);
1257    try {
1258        await deleteKeyItem(keyAlias, huksOptions)
1259            .then ((data) => {
1260                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
1261            })
1262            .catch(error => {
1263                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
1264            });
1265    } catch (error) {
1266        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
1267    }
1268}
1269
1270function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
1271    return new Promise((resolve, reject) => {
1272        try {
1273            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
1274                if (error) {
1275                    reject(error);
1276                } else {
1277                    resolve(data);
1278                }
1279            });
1280        } catch (error) {
1281            throw(error);
1282        }
1283    });
1284}
1285
1286let IV = '0000000000000000';
1287let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string';
1288let srcKeyAlias = 'huksCipherSm4SrcKeyAlias';
1289let encryptUpdateResult = new Array();
1290let handle;
1291let updateResult = new Array();
1292let finishOutData;
1293
1294async function testSm4Cipher() {
1295    /* Integrate the key generation parameter set and key encryption parameter set. */
1296    let properties = new Array();
1297    properties[0] = {
1298        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1299        value: huks.HuksKeyAlg.HUKS_ALG_SM4,
1300    }
1301    properties[1] = {
1302        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1303        value:
1304        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
1305        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
1306    }
1307    properties[2] = {
1308        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1309        value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
1310    }
1311    properties[3] = {
1312        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
1313        value: huks.HuksCipherMode.HUKS_MODE_CBC,
1314    }
1315    properties[4] = {
1316        tag: huks.HuksTag.HUKS_TAG_PADDING,
1317        value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
1318    }
1319    let huksOptions = {
1320        properties: properties,
1321        inData: new Uint8Array(new Array())
1322    }
1323
1324    let propertiesEncrypt = new Array();
1325    propertiesEncrypt[0] = {
1326        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1327        value: huks.HuksKeyAlg.HUKS_ALG_SM4,
1328    }
1329    propertiesEncrypt[1] = {
1330        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1331        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT,
1332    }
1333    propertiesEncrypt[2] = {
1334        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1335        value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
1336    }
1337    propertiesEncrypt[3] = {
1338        tag: huks.HuksTag.HUKS_TAG_PADDING,
1339        value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
1340    }
1341    propertiesEncrypt[4] = {
1342        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
1343        value: huks.HuksCipherMode.HUKS_MODE_CBC,
1344    }
1345    propertiesEncrypt[5] = {
1346        tag: huks.HuksTag.HUKS_TAG_IV,
1347        value: StringToUint8Array(IV),
1348    }
1349    let encryptOptions = {
1350        properties: propertiesEncrypt,
1351        inData: new Uint8Array(new Array())
1352    }
1353
1354    /* Generate a key. */
1355    await publicGenKeyFunc(srcKeyAlias, huksOptions);
1356
1357    /* Encrypt the key. */
1358    await publicInitFunc(srcKeyAlias, encryptOptions);
1359
1360    encryptOptions.inData = StringToUint8Array(cipherInData);
1361    await publicUpdateFunc(handle, encryptOptions);
1362    encryptUpdateResult = updateResult;
1363
1364    encryptOptions.inData = new Uint8Array(new Array());
1365    await publicFinishFunc(handle, encryptOptions);
1366    if (finishOutData === cipherInData) {
1367        console.info('test finish encrypt err ');
1368    } else {
1369        console.info('test finish encrypt success');
1370    }
1371
1372    /* Modify the key encryption parameter set to the decryption parameter set. */
1373    propertiesEncrypt.splice(1, 1, {
1374        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1375        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
1376    });
1377    let decryptOptions = {
1378        properties: propertiesEncrypt,
1379        inData: new Uint8Array(new Array())
1380    }
1381
1382    /* Decrypt the key. */
1383    await publicInitFunc(srcKeyAlias, decryptOptions);
1384
1385    decryptOptions.inData = new Uint8Array(encryptUpdateResult);
1386    await publicUpdateFunc(handle, decryptOptions);
1387
1388    decryptOptions.inData = new Uint8Array(new Array());
1389    await publicFinishFunc(handle, decryptOptions);
1390    if (finishOutData === cipherInData) {
1391        console.info('test finish decrypt success ');
1392    } else {
1393        console.info('test finish decrypt err');
1394    }
1395
1396    await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
1397}
1398
1399@Entry
1400@Component
1401struct Index {
1402    build() {
1403        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
1404            Button() {
1405                Text('testSm4Cipher')
1406                    .fontSize(30)
1407                    .fontWeight(FontWeight.Bold)
1408            }.type(ButtonType.Capsule)
1409            .margin({
1410                top: 20
1411            })
1412            .backgroundColor('#0D9FFB')
1413            .onClick(()=>{
1414                testSm4Cipher();
1415            })
1416        }
1417        .width('100%')
1418        .height('100%')
1419    }
1420}
1421```
1422
1423**Example 2:**
1424
1425```ts
1426/* The cipher operation supports RSA, AES, and SM4 keys.
1427 *
1428 * The following uses the Promise() operation of an AES128 GCM key as an example.
1429 */
1430import huks from '@ohos.security.huks';
1431
1432function StringToUint8Array(str) {
1433    let arr = [];
1434    for (let i = 0, j = str.length; i < j; ++i) {
1435        arr.push(str.charCodeAt(i));
1436    }
1437    return new Uint8Array(arr);
1438}
1439
1440function Uint8ArrayToString(fileData) {
1441    let dataString = '';
1442    for (let i = 0; i < fileData.length; i++) {
1443        dataString += String.fromCharCode(fileData[i]);
1444    }
1445    return dataString;
1446}
1447
1448async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1449    console.info(`enter callback generateKeyItem`);
1450    try {
1451        await generateKeyItem(keyAlias, huksOptions)
1452            .then((data) => {
1453                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
1454            })
1455            .catch(error => {
1456                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
1457            });
1458    } catch (error) {
1459        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
1460    }
1461}
1462
1463function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
1464    return new Promise((resolve, reject) => {
1465        try {
1466            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
1467                if (error) {
1468                    reject(error);
1469                } else {
1470                    resolve(data);
1471                }
1472            });
1473        } catch (error) {
1474            throw(error);
1475        }
1476    });
1477}
1478
1479async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1480    console.info(`enter promise doInit`);
1481    try {
1482        await huks.initSession(keyAlias, huksOptions)
1483            .then ((data) => {
1484                console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
1485                handle = data.handle;
1486            })
1487            .catch(error => {
1488                console.error(`promise: doInit key failed, code: ${error.code}, msg: ${error.message}`);
1489            });
1490    } catch (error) {
1491        console.error(`promise: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
1492    }
1493}
1494
1495async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
1496    console.info(`enter callback doUpdate`);
1497    try {
1498        await updateSession(handle, huksOptions)
1499            .then ((data) => {
1500                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
1501                updateResult = Array.from(data.outData);
1502            })
1503            .catch(error => {
1504                console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
1505            });
1506    } catch (error) {
1507        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
1508    }
1509}
1510
1511function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
1512    return new Promise((resolve, reject) => {
1513        try {
1514            huks.updateSession(handle, huksOptions, function (error, data) {
1515                if (error) {
1516                    reject(error);
1517                } else {
1518                    resolve(data);
1519                }
1520            });
1521        } catch (error) {
1522            throw(error);
1523        }
1524    });
1525}
1526
1527async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
1528    console.info(`enter callback doFinish`);
1529    try {
1530        await finishSession(handle, huksOptions)
1531            .then ((data) => {
1532                updateResult = updateResult.concat(Array.from(data.outData));
1533                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
1534            })
1535            .catch(error => {
1536                console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
1537            });
1538    } catch (error) {
1539        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
1540    }
1541}
1542
1543function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
1544    return new Promise((resolve, reject) => {
1545        try {
1546            huks.finishSession(handle, huksOptions, function (error, data) {
1547                if (error) {
1548                    reject(error);
1549                } else {
1550                    resolve(data);
1551                }
1552            });
1553        } catch (error) {
1554            throw(error);
1555        }
1556    });
1557}
1558
1559async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1560    console.info(`enter callback deleteKeyItem`);
1561    try {
1562        await deleteKeyItem(keyAlias, huksOptions)
1563            .then ((data) => {
1564                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
1565            })
1566            .catch(error => {
1567                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
1568            });
1569    } catch (error) {
1570        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
1571    }
1572}
1573
1574function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
1575    return new Promise((resolve, reject) => {
1576        try {
1577            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
1578                if (error) {
1579                    reject(error);
1580                } else {
1581                    resolve(data);
1582                }
1583            });
1584        } catch (error) {
1585            throw(error);
1586        }
1587    });
1588}
1589
1590let AAD = '0000000000000000';
1591let NONCE = '000000000000';
1592let AEAD = '0000000000000000';
1593let cipherInData = 'Hks_AES_Cipher_Test_00000000000000000000000000000000000000000000000000000_string';
1594let srcKeyAlias = 'huksCipherSm4SrcKeyAlias';
1595let updateResult = new Array();
1596let encryptUpdateResult = new Array();
1597let decryptUpdateResult = new Array();
1598let handle;
1599let finishOutData;
1600
1601async function testAesCipher() {
1602    /* Integrate the key generation parameter set and key encryption parameter set. */
1603    let properties = new Array();
1604    properties[0] = {
1605        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1606        value: huks.HuksKeyAlg.HUKS_ALG_AES,
1607    }
1608    properties[1] = {
1609        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1610        value:
1611        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
1612        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
1613    }
1614    properties[2] = {
1615        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1616        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
1617    }
1618    properties[3] = {
1619        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
1620        value: huks.HuksCipherMode.HUKS_MODE_GCM,
1621    }
1622    properties[4] = {
1623        tag: huks.HuksTag.HUKS_TAG_PADDING,
1624        value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
1625    }
1626    let huksOptions = {
1627        properties: properties,
1628        inData: new Uint8Array(new Array())
1629    }
1630
1631    let propertiesEncrypt = new Array();
1632    propertiesEncrypt[0] = {
1633        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1634        value: huks.HuksKeyAlg.HUKS_ALG_AES,
1635    }
1636    propertiesEncrypt[1] = {
1637        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1638        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT,
1639    }
1640    propertiesEncrypt[2] = {
1641        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1642        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
1643    }
1644    propertiesEncrypt[3] = {
1645        tag: huks.HuksTag.HUKS_TAG_PADDING,
1646        value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
1647    }
1648    propertiesEncrypt[4] = {
1649        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
1650        value: huks.HuksCipherMode.HUKS_MODE_GCM,
1651    }
1652    propertiesEncrypt[5] = {
1653        tag: huks.HuksTag.HUKS_TAG_DIGEST,
1654        value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
1655    }
1656    propertiesEncrypt[6] = {
1657        tag: huks.HuksTag.HUKS_TAG_ASSOCIATED_DATA,
1658        value: StringToUint8Array(AAD),
1659    }
1660    propertiesEncrypt[7] = {
1661        tag: huks.HuksTag.HUKS_TAG_NONCE,
1662        value: StringToUint8Array(NONCE),
1663    }
1664    propertiesEncrypt[8] = {
1665        tag: huks.HuksTag.HUKS_TAG_AE_TAG,
1666        value: StringToUint8Array(AEAD),
1667    }
1668    let encryptOptions = {
1669        properties: propertiesEncrypt,
1670        inData: new Uint8Array(new Array())
1671    }
1672
1673    /* Generate a key. */
1674    await publicGenKeyFunc(srcKeyAlias, huksOptions);
1675
1676    /* Encrypt the key. */
1677    await publicInitFunc(srcKeyAlias, encryptOptions);
1678
1679    encryptOptions.inData = StringToUint8Array(cipherInData.slice(0,64));
1680    await publicUpdateFunc(handle, encryptOptions);
1681    encryptUpdateResult = updateResult;
1682
1683    encryptOptions.inData = StringToUint8Array(cipherInData.slice(64,80));
1684    await publicFinishFunc(handle, encryptOptions);
1685    encryptUpdateResult = updateResult;
1686    finishOutData = Uint8ArrayToString(new Uint8Array(encryptUpdateResult));
1687    if (finishOutData === cipherInData) {
1688        console.info('test finish encrypt err ');
1689    } else {
1690        console.info('test finish encrypt success');
1691    }
1692
1693    /* Modify the key encryption parameter set to the decryption parameter set. */
1694    propertiesEncrypt.splice(1, 1, {
1695        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1696        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
1697    });
1698    propertiesEncrypt.splice(8, 1, {
1699        tag: huks.HuksTag.HUKS_TAG_AE_TAG,
1700        value: new Uint8Array(encryptUpdateResult.splice(encryptUpdateResult.length - 16,encryptUpdateResult.length))
1701    });
1702    let decryptOptions = {
1703        properties: propertiesEncrypt,
1704        inData: new Uint8Array(new Array())
1705    }
1706
1707    /* Decrypt the key. */
1708    await publicInitFunc(srcKeyAlias, decryptOptions);
1709
1710    decryptOptions.inData = new Uint8Array(encryptUpdateResult.slice(0,64));
1711    await publicUpdateFunc(handle, decryptOptions);
1712    decryptUpdateResult = updateResult;
1713
1714    decryptOptions.inData = new Uint8Array(encryptUpdateResult.slice(64,encryptUpdateResult.length));
1715    await publicFinishFunc(handle, decryptOptions);
1716    decryptUpdateResult = updateResult;
1717    finishOutData = Uint8ArrayToString(new Uint8Array(decryptUpdateResult));
1718    if (finishOutData === cipherInData) {
1719        console.info('test finish decrypt success ');
1720    } else {
1721        console.info('test finish decrypt err');
1722    }
1723
1724    await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
1725}
1726
1727@Entry
1728@Component
1729struct Index {
1730    build() {
1731        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
1732            Button() {
1733                Text('testAesCipher')
1734                    .fontSize(30)
1735                    .fontWeight(FontWeight.Bold)
1736            }.type(ButtonType.Capsule)
1737            .margin({
1738                top: 20
1739            })
1740            .backgroundColor('#0D9FFB')
1741            .onClick(()=>{
1742                testAesCipher();
1743            })
1744        }
1745        .width('100%')
1746        .height('100%')
1747    }
1748}
1749```
1750
1751### Signing and Signature Verification
1752
1753The data to be sent can be signed with a unique signature for security purposes. Then, the receiver needs to verify the signature when receiving the data.
1754
1755The development procedure is as follows:
1756
17571. Generate a key.
17582. Use the key to sign the data to be sent.
17593. Export the signature key.
17604. Import the signature key.
17615. Verify the signature.
1762
1763**Supported key types**:
1764
1765Only **HksInit()** has requirements on parameters in **paramSet**. The other Init-Update-Finish APIs have no requirements on **paramSet**.
1766
1767| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE                                            | HUKS_ALG_PURPOSE                               | HUKS_ALG_PADDING        | HUKS_TAG_DIGEST                                              |
1768| ------------------ | ------------------------------------------------------------ | ---------------------------------------------- | ----------------------- | ------------------------------------------------------------ |
1769| HUKS_ALG_RSA       | HUKS_RSA_KEY_SIZE_512, HUKS_RSA_KEY_SIZE_768, HUKS_RSA_KEY_SIZE_1024,  HUKS_RSA_KEY_SIZE_2048, HUKS_RSA_KEY_SIZE_3072, HUKS_RSA_KEY_SIZE_4096| HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY | HUKS_PADDING_PKCS1_V1_5 | HUKS_DIGEST_MD5, HUKS_DIGEST_NONE, HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512|
1770| HUKS_ALG_RSA       | HUKS_RSA_KEY_SIZE_512, HUKS_RSA_KEY_SIZE_768, HUKS_RSA_KEY_SIZE_1024,  HUKS_RSA_KEY_SIZE_2048, HUKS_RSA_KEY_SIZE_3072, HUKS_RSA_KEY_SIZE_4096| HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY | HUKS_PADDING_PSS        | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512|
1771| HUKS_ALG_DSA       | HUKS_RSA_KEY_SIZE_1024                                       | HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY | Optional             | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512|
1772| HUKS_ALG_ECC       | HUKS_ECC_KEY_SIZE_224, HUKS_ECC_KEY_SIZE_256, HUKS_ECC_KEY_SIZE_384, HUKS_ECC_KEY_SIZE_521| HUKS_KEY_PURPOSE_SIGN  HUKS_KEY_PURPOSE_VERIFY | Optional             | HUKS_DIGEST_NONE, HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512|
1773
1774The signing and signature verification using Ed25519 involves a hash operation in the algorithm engine. Therefore, the Init-Update-Finish processing is special.
1775
1776In the **update()** process, **inData** is sent to HUKS Core and recorded in a .ctx file, without performing hash operation. The signing and signature verification calculations are performed on the combined **inData** in the **finish()** operation.
1777
1778| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE            | HUKS_ALG_PURPOSE                                |
1779| ------------------ | ---------------------------- | ----------------------------------------------- |
1780| HUKS_ALG_ED25519   | HUKS_CURVE25519_KEY_SIZE_256 | HUKS_KEY_PURPOSE_SIGN   HUKS_KEY_PURPOSE_VERIFY |
1781
1782> **NOTE**<br>
1783>
1784> The key alias cannot exceed 64 bytes.
1785
1786Before you get started, understand the following variables:
1787
1788| Parameter           | Type       | Mandatory| Description                    |
1789| ----------------- | ----------- | ---- | ------------------------ |
1790| generateKeyAlias  | string      | Yes  | Alias of the key to generate.          |
1791| importKeyAlias    | string      | Yes  | Alias of the key imported.          |
1792| genrateKeyOptions | HuksOptions | Yes  | Tags required for generating the key.|
1793| signOptions       | HuksOptions | Yes  | Tags required for signing.|
1794| verifyOptions     | HuksOptions | Yes  | Tags required for verifying the signature.|
1795
1796For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
1797
1798**Example**
1799
1800```ts
1801/*The Sign() and Verify() operations support RSA, ECC, SM2, ED25519, and DSA keys.
1802 *
1803 * The following uses an SM2 key in callback-based APIs as an example.
1804 */
1805import huks from '@ohos.security.huks';
1806
1807function StringToUint8Array(str) {
1808    let arr = [];
1809    for (let i = 0, j = str.length; i < j; ++i) {
1810        arr.push(str.charCodeAt(i));
1811    }
1812    return new Uint8Array(arr);
1813}
1814
1815async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1816    console.info(`enter callback generateKeyItem`);
1817    try {
1818        await generateKeyItem(keyAlias, huksOptions)
1819            .then((data) => {
1820                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
1821            })
1822            .catch(error => {
1823                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
1824            });
1825    } catch (error) {
1826        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
1827    }
1828}
1829
1830function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
1831    return new Promise((resolve, reject) => {
1832        try {
1833            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
1834                if (error) {
1835                    reject(error);
1836                } else {
1837                    resolve(data);
1838                }
1839            });
1840        } catch (error) {
1841            throw(error);
1842        }
1843    });
1844}
1845
1846async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1847    console.info(`enter callback doInit`);
1848    try {
1849        await initSession(keyAlias, huksOptions)
1850            .then ((data) => {
1851                console.info(`callback1: doInit success, data = ${JSON.stringify(data)}`);
1852                handle = data.handle;
1853            })
1854            .catch((error) => {
1855                console.error(`callback1: doInit failed, code: ${error.code}, msg: ${error.message}`);
1856            });
1857    } catch (error) {
1858        console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
1859    }
1860}
1861
1862function initSession(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksSessionHandle> {
1863    return new Promise((resolve, reject) => {
1864        try {
1865            huks.initSession(keyAlias, huksOptions, function (error, data) {
1866                if (error) {
1867                    reject(error);
1868                } else {
1869                    resolve(data);
1870                }
1871            });
1872        } catch (error) {
1873            throw(error);
1874        }
1875    });
1876}
1877
1878async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
1879    console.info(`enter callback doUpdate`);
1880    try {
1881        await updateSession(handle, huksOptions)
1882            .then ((data) => {
1883                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
1884            })
1885            .catch(error => {
1886                console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
1887            });
1888    } catch (error) {
1889        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
1890    }
1891}
1892
1893function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
1894    return new Promise((resolve, reject) => {
1895        try {
1896            huks.updateSession(handle, huksOptions, function (error, data) {
1897                if (error) {
1898                    reject(error);
1899                } else {
1900                    resolve(data);
1901                }
1902            });
1903        } catch (error) {
1904            throw(error);
1905        }
1906    });
1907}
1908
1909async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
1910    console.info(`enter callback doFinish`);
1911    try {
1912        await finishSession(handle, huksOptions)
1913            .then ((data) => {
1914                finishOutData = data.outData;;
1915                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
1916            })
1917            .catch(error => {
1918                console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
1919            });
1920    } catch (error) {
1921        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
1922    }
1923}
1924
1925function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
1926    return new Promise((resolve, reject) => {
1927        try {
1928            huks.finishSession(handle, huksOptions, function (error, data) {
1929                if (error) {
1930                    reject(error);
1931                } else {
1932                    resolve(data);
1933                }
1934            });
1935        } catch (error) {
1936            throw(error);
1937        }
1938    });
1939}
1940
1941async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1942    console.info(`enter callback export`);
1943    try {
1944        await exportKeyItem(keyAlias, huksOptions)
1945            .then ((data) => {
1946                console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`);
1947                exportKey = data.outData;
1948            })
1949            .catch(error => {
1950                console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`);
1951            });
1952    } catch (error) {
1953        console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
1954    }
1955}
1956
1957function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
1958    return new Promise((resolve, reject) => {
1959        try {
1960            huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
1961                if (error) {
1962                    reject(error);
1963                } else {
1964                    resolve(data);
1965                }
1966            });
1967        } catch (error) {
1968            throw(error);
1969        }
1970    });
1971}
1972
1973async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
1974    console.info(`enter promise importKeyItem`);
1975    try {
1976        await importKeyItem(keyAlias, huksOptions)
1977            .then ((data) => {
1978                console.info(`callback: importKeyItem success, data = ${JSON.stringify(data)}`);
1979            })
1980            .catch(error => {
1981                console.error(`callback: importKeyItem failed, code: ${error.code}, msg: ${error.message}`);
1982            });
1983    } catch (error) {
1984        console.error(`callback: importKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
1985    }
1986}
1987
1988function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
1989    return new Promise((resolve, reject) => {
1990        try {
1991            huks.importKeyItem(keyAlias, huksOptions, function (error, data) {
1992                if (error) {
1993                    reject(error);
1994                } else {
1995                    resolve(data);
1996                }
1997            });
1998        } catch (error) {
1999            throw(error);
2000        }
2001    });
2002}
2003
2004async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2005    console.info(`enter callback deleteKeyItem`);
2006    try {
2007        await deleteKeyItem(keyAlias, huksOptions)
2008            .then ((data) => {
2009                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
2010            })
2011            .catch(error => {
2012                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
2013            });
2014    } catch (error) {
2015        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
2016    }
2017}
2018
2019function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
2020    return new Promise((resolve, reject) => {
2021        try {
2022            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
2023                if (error) {
2024                    reject(error);
2025                } else {
2026                    resolve(data);
2027                }
2028            });
2029        } catch (error) {
2030            throw(error);
2031        }
2032    });
2033}
2034
2035let signVerifyInData1 = 'signVerifyInDataForTestFirstText';
2036let signVerifyInData2 = 'signVerifyInDataForTestSecondText';
2037let signVerifyInData = [signVerifyInData1, signVerifyInData2];
2038let generateKeyAlias = 'generateKeyAliasForTest';
2039let importKeyAlias = 'importKeyAliasForTest';
2040let handle;
2041let exportKey;
2042let finishOutData;
2043
2044/* Configure the parameters for generating the key. */
2045let generateKeyProperties = new Array();
2046generateKeyProperties[0] = {
2047    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2048    value: huks.HuksKeyAlg.HUKS_ALG_SM2,
2049}
2050generateKeyProperties[1] = {
2051    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
2052    value:
2053    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN |
2054    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY,
2055}
2056generateKeyProperties[2] = {
2057    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2058    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256,
2059}
2060generateKeyProperties[3] = {
2061    tag: huks.HuksTag.HUKS_TAG_DIGEST,
2062    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3,
2063}
2064let genrateKeyOptions = {
2065    properties: generateKeyProperties,
2066    inData: new Uint8Array(new Array())
2067}
2068
2069/* Configure the parameters for signing. */
2070let signProperties = new Array();
2071signProperties[0] = {
2072    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2073    value: huks.HuksKeyAlg.HUKS_ALG_SM2,
2074}
2075signProperties[1] = {
2076    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
2077    value:
2078    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN
2079}
2080signProperties[2] = {
2081    tag: huks.HuksTag.HUKS_TAG_DIGEST,
2082    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3,
2083}
2084signProperties[3] = {
2085    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2086    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256,
2087}
2088let signOptions = {
2089    properties: signProperties,
2090    inData: new Uint8Array(new Array())
2091}
2092
2093/* Configure the parameters for signature verification. */
2094let verifyProperties = new Array();
2095verifyProperties[0] = {
2096    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2097    value: huks.HuksKeyAlg.HUKS_ALG_SM2,
2098}
2099verifyProperties[1] = {
2100    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
2101    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY
2102}
2103verifyProperties[2] = {
2104    tag: huks.HuksTag.HUKS_TAG_DIGEST,
2105    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3,
2106}
2107verifyProperties[3] = {
2108    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2109    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256,
2110}
2111let verifyOptions = {
2112    properties: verifyProperties,
2113    inData: new Uint8Array(new Array())
2114}
2115
2116async function testSm2SignVerify() {
2117    /* Generate a key. */
2118    await publicGenKeyFunc(generateKeyAlias, genrateKeyOptions);
2119
2120    /* Generate a signature. */
2121    let signHandle;
2122    let signFinishOutData;
2123    await publicInitFunc(generateKeyAlias, signOptions);
2124
2125    signHandle = handle;
2126    for (var index = 0; index < signVerifyInData.length; index++) {
2127        signOptions.inData = StringToUint8Array(signVerifyInData[index]);
2128        await publicUpdateFunc(signHandle, signOptions);
2129    }
2130
2131    signOptions.inData = new Uint8Array(new Array());
2132    await publicFinishFunc(signHandle, signOptions);
2133    signFinishOutData = finishOutData;
2134
2135    /* Export the key. */
2136    await publicExportKeyFunc(generateKeyAlias, genrateKeyOptions);
2137
2138    /* Import the key. */
2139    verifyOptions.inData = exportKey;
2140    await publicImportKeyFunc(importKeyAlias, verifyOptions);
2141
2142    /* Verify the signature. */
2143    let verifyHandle;
2144    await publicInitFunc(importKeyAlias, verifyOptions);
2145
2146    verifyHandle = handle;
2147
2148    for (var index = 0; index < signVerifyInData.length; index++) {
2149        verifyOptions.inData = StringToUint8Array(signVerifyInData[index]);
2150        await publicUpdateFunc(verifyHandle, verifyOptions);
2151    }
2152
2153    verifyOptions.inData = signFinishOutData;
2154    await publicFinishFunc(verifyHandle, verifyOptions);
2155
2156    await publicDeleteKeyFunc(generateKeyAlias, genrateKeyOptions);
2157    await publicDeleteKeyFunc(importKeyAlias, genrateKeyOptions);
2158}
2159
2160@Entry
2161@Component
2162struct Index {
2163    build() {
2164        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
2165            Button() {
2166                Text('testSm2SignVerify')
2167                    .fontSize(30)
2168                    .fontWeight(FontWeight.Bold)
2169            }.type(ButtonType.Capsule)
2170            .margin({
2171                top: 20
2172            })
2173            .backgroundColor('#0D9FFB')
2174            .onClick(()=>{
2175                testSm2SignVerify();
2176            })
2177        }
2178        .width('100%')
2179        .height('100%')
2180    }
2181}
2182```
2183
2184### Key Agreement
2185
2186Two or more objects communicate with each other based on the same session key.
2187
2188The development procedure is as follows:
2189
21901. Generate two keys.
21912. Export the keys separately.
21923. Perform key agreement.
2193
2194**Supported key types**:
2195
2196The **HksInit()** and **HksFinish()** APIs have requirements on **paramSet**. The **HksUpdate()** API has no requirements on **paramSet**.
2197
2198Requirements of **HksInit()** for **paramSet**:
2199
2200| HUKS_ALG_ALGORITHM | HUKS_ALG_KEY_SIZE                                            | HUKS_ALG_PURPOSE       |
2201| ------------------ | ------------------------------------------------------------ | ---------------------- |
2202| HUKS_ALG_ECDH      | HUKS_ECC_KEY_SIZE_224, HUKS_ECC_KEY_SIZE_256, HUKS_ECC_KEY_SIZE_384, HUKS_ECC_KEY_SIZE_521| HUKS_KEY_PURPOSE_AGREE |
2203| HUKS_ALG_DH        | HUKS_DH_KEY_SIZE_2048, HUKS_DH_KEY_SIZE_3072, HUKS_DH_KEY_SIZE_4096| HUKS_KEY_PURPOSE_AGREE |
2204| HUKS_ALG_X25519    | HUKS_CURVE25519_KEY_SIZE_256                                 | HUKS_KEY_PURPOSE_AGREE |
2205
2206Requirements of **HksFinish()** for **paramSet**:
2207
2208The derived key is used as a symmetric key.
2209
2210| HUKS_TAG_KEY_STORAGE_FLAG      | HUKS_TAG_KEY_ALIAS | HUKS_TAG_IS_KEY_ALIAS | HUKS_TAG_ALGORITHM | HUKS_TAG_KEY_SIZE                                            | HUKS_TAG_PURPOSE                                   | HUKS_TAG_PADDING   | HUKS_TAG_DIGEST                                              | HUKS_TAG_BLOCK_MODE                         |
2211| ------------------------------ | ------------------ | --------------------- | ------------------ | ------------------------------------------------------------ | -------------------------------------------------- | ------------------ | ------------------------------------------------------------ | ------------------------------------------- |
2212| **HUKS_STORAGE_TEMP** or not set| Not required            | TRUE                  | Not required            | Not required                                                      | Not required                                            | Not required            | Not required                                                      | Not required                                     |
2213| HUKS_STORAGE_PERSISTENT        | (Mandatory) Maximum 64 bytes.| TRUE                  | HUKS_ALG_AES       | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_PADDING_PKCS7 | Optional                                                  | HUKS_MODE_CCM  HUKS_MODE_GCM  HUKS_MODE_CTP |
2214| HUKS_STORAGE_PERSISTENT        | (Mandatory) Maximum 64 bytes.| TRUE                  | HUKS_ALG_AES       | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_DERIVE                            | Optional        | HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512  | Optional                                 |
2215| HUKS_STORAGE_PERSISTENT        | (Mandatory) Maximum 64 bytes.| TRUE                  | HUKS_ALG_HMAC      | Multiple of 8, in bits                                        | HUKS_KEY_PURPOSE_MAC                               | Optional        | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Optional                                 |
2216
2217> **NOTE**<br>
2218>
2219> The length of the key after agreement (converted into bits) must be greater than or equal to the selected **HUKS_TAG_KEY_SIZE**.
2220>
2221> The key alias cannot exceed 64 bytes.
2222
2223Before you get started, understand the following variables:
2224
2225| Parameter             | Type       | Mandatory| Description                                  |
2226| ------------------- | ----------- | ---- | -------------------------------------- |
2227| srcKeyAliasFirst    | string      | Yes  | Alias of the key generated.                        |
2228| srcKeyAliasSecond   | string      | Yes  | Alias of key 2 generated.          |
2229| huksOptions         | HuksOptions | Yes  | Tags required for generating the key.              |
2230| finishOptionsFrist  | HuksOptions | Yes  | Tags required for key agreement.              |
2231| finishOptionsSecond | HuksOptions | Yes  | Tags required for key agreement.|
2232
2233For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
2234
2235**Example**
2236
2237```ts
2238/* The agree() operation supports ECDH, DH, and X25519 keys.
2239 *
2240 * The following uses the Promise() operation of an X25519 256-bit TEMP key as an example.
2241 */
2242import huks from '@ohos.security.huks';
2243
2244function StringToUint8Array(str) {
2245    let arr = [];
2246    for (let i = 0, j = str.length; i < j; ++i) {
2247        arr.push(str.charCodeAt(i));
2248    }
2249    return new Uint8Array(arr);
2250}
2251
2252async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2253    console.info(`enter callback generateKeyItem`);
2254    try {
2255        await generateKeyItem(keyAlias, huksOptions)
2256            .then((data) => {
2257                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
2258            })
2259            .catch(error => {
2260                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
2261            });
2262    } catch (error) {
2263        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
2264    }
2265}
2266
2267function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
2268    return new Promise((resolve, reject) => {
2269        try {
2270            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
2271                if (error) {
2272                    reject(error);
2273                } else {
2274                    resolve(data);
2275                }
2276            });
2277        } catch (error) {
2278            throw(error);
2279        }
2280    });
2281}
2282
2283async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2284    console.info(`enter callback doInit`);
2285    try {
2286        await initSession(keyAlias, huksOptions)
2287            .then ((data) => {
2288                console.info(`callback1: doInit success, data = ${JSON.stringify(data)}`);
2289                handle = data.handle;
2290            })
2291            .catch((error) => {
2292                console.error(`callback1: doInit failed, code: ${error.code}, msg: ${error.message}`);
2293            });
2294    } catch (error) {
2295        console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
2296    }
2297}
2298
2299function initSession(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksSessionHandle> {
2300    return new Promise((resolve, reject) => {
2301        try {
2302            huks.initSession(keyAlias, huksOptions, function (error, data) {
2303                if (error) {
2304                    reject(error);
2305                } else {
2306                    resolve(data);
2307                }
2308            });
2309        } catch (error) {
2310            throw(error);
2311        }
2312    });
2313}
2314
2315async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
2316    console.info(`enter callback doUpdate`);
2317    try {
2318        await updateSession(handle, huksOptions)
2319            .then ((data) => {
2320                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
2321            })
2322            .catch(error => {
2323                console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
2324            });
2325    } catch (error) {
2326        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
2327    }
2328}
2329
2330function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
2331    return new Promise((resolve, reject) => {
2332        try {
2333            huks.updateSession(handle, huksOptions, function (error, data) {
2334                if (error) {
2335                    reject(error);
2336                } else {
2337                    resolve(data);
2338                }
2339            });
2340        } catch (error) {
2341            throw(error);
2342        }
2343    });
2344}
2345
2346async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
2347    console.info(`enter callback doFinish`);
2348    try {
2349        await finishSession(handle, huksOptions)
2350            .then ((data) => {
2351                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
2352            })
2353            .catch(error => {
2354                console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
2355            });
2356    } catch (error) {
2357        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
2358    }
2359}
2360
2361function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
2362    return new Promise((resolve, reject) => {
2363        try {
2364            huks.finishSession(handle, huksOptions, function (error, data) {
2365                if (error) {
2366                    reject(error);
2367                } else {
2368                    resolve(data);
2369                }
2370            });
2371        } catch (error) {
2372            throw(error);
2373        }
2374    });
2375}
2376
2377async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2378    console.info(`enter callback export`);
2379    try {
2380        await exportKeyItem(keyAlias, huksOptions)
2381            .then ((data) => {
2382                console.info(`callback: exportKeyItem success, data = ${JSON.stringify(data)}`);
2383                exportKey = data.outData;
2384            })
2385            .catch(error => {
2386                console.error(`callback: exportKeyItem failed, code: ${error.code}, msg: ${error.message}`);
2387            });
2388    } catch (error) {
2389        console.error(`callback: exportKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
2390    }
2391}
2392
2393function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
2394    return new Promise((resolve, reject) => {
2395        try {
2396            huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
2397                if (error) {
2398                    reject(error);
2399                } else {
2400                    resolve(data);
2401                }
2402            });
2403        } catch (error) {
2404            throw(error);
2405        }
2406    });
2407}
2408
2409async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2410    console.info(`enter callback deleteKeyItem`);
2411    try {
2412        await deleteKeyItem(keyAlias, huksOptions)
2413            .then ((data) => {
2414                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
2415            })
2416            .catch(error => {
2417                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
2418            });
2419    } catch (error) {
2420        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
2421    }
2422}
2423
2424function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
2425    return new Promise((resolve, reject) => {
2426        try {
2427            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
2428                if (error) {
2429                    reject(error);
2430                } else {
2431                    resolve(data);
2432                }
2433            });
2434        } catch (error) {
2435            throw(error);
2436        }
2437    });
2438}
2439
2440let srcKeyAliasFirst = "AgreeX25519KeyFirstAlias";
2441let srcKeyAliasSecond = "AgreeX25519KeySecondAlias";
2442let agreeX25519InData = 'AgreeX25519TestIndata';
2443let handle;
2444let exportKey;
2445let exportKeyFrist;
2446let exportKeySecond;
2447
2448async function testAgree() {
2449    /* Configure the parameters for generating the key. */
2450    let properties = new Array();
2451    properties[0] = {
2452        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2453        value: huks.HuksKeyAlg.HUKS_ALG_X25519,
2454    }
2455    properties[1] = {
2456        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
2457        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE,
2458    }
2459    properties[2] = {
2460        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2461        value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256,
2462    }
2463    properties[3] = {
2464        tag: huks.HuksTag.HUKS_TAG_DIGEST,
2465        value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
2466    }
2467    properties[4] = {
2468        tag: huks.HuksTag.HUKS_TAG_PADDING,
2469        value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
2470    }
2471    properties[5] = {
2472        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
2473        value: huks.HuksCipherMode.HUKS_MODE_CBC,
2474    }
2475    let HuksOptions = {
2476        properties: properties,
2477        inData: new Uint8Array(new Array())
2478    }
2479
2480    /* 1. Generate two keys and export them. */
2481    await publicGenKeyFunc(srcKeyAliasFirst, HuksOptions);
2482    await publicGenKeyFunc(srcKeyAliasSecond, HuksOptions);
2483
2484    await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions);
2485    exportKeyFrist = exportKey;
2486    await publicExportKeyFunc(srcKeyAliasFirst, HuksOptions);
2487    exportKeySecond = exportKey;
2488
2489    /* Configure parameters for the first key agreement. */
2490    let finishProperties = new Array();
2491    finishProperties[0] = {
2492        tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG,
2493        value: huks.HuksKeyStorageType.HUKS_STORAGE_TEMP,
2494    }
2495    finishProperties[1] = {
2496        tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
2497        value: true
2498    }
2499    finishProperties[2] = {
2500        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2501        value: huks.HuksKeyAlg.HUKS_ALG_AES,
2502    }
2503    finishProperties[3] = {
2504        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2505        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
2506    }
2507    finishProperties[4] = {
2508        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
2509        value:
2510        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
2511        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
2512    }
2513    finishProperties[5] = {
2514        tag: huks.HuksTag.HUKS_TAG_DIGEST,
2515        value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
2516    }
2517    finishProperties[6] = {
2518        tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
2519        value: StringToUint8Array(srcKeyAliasFirst+ 'final'),
2520    }
2521    finishProperties[7] = {
2522        tag: huks.HuksTag.HUKS_TAG_PADDING,
2523        value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
2524    }
2525    finishProperties[8] = {
2526        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
2527        value: huks.HuksCipherMode.HUKS_MODE_ECB,
2528    }
2529    let finishOptionsFrist = {
2530        properties: finishProperties,
2531        inData: StringToUint8Array(agreeX25519InData)
2532    }
2533
2534    /* Obtain the first agreed key. */
2535    await publicInitFunc(srcKeyAliasFirst, HuksOptions);
2536    HuksOptions.inData = exportKeySecond;
2537    await publicUpdateFunc(handle, HuksOptions);
2538    await publicFinishFunc(handle, finishOptionsFrist);
2539
2540    /* Configure parameters for the second key agreement. */
2541    let finishOptionsSecond = {
2542        properties: finishProperties,
2543        inData: StringToUint8Array(agreeX25519InData)
2544    }
2545    finishOptionsSecond.properties.splice(6, 1, {
2546        tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
2547        value: StringToUint8Array(srcKeyAliasSecond + 'final'),
2548    })
2549
2550    /* Obtain the second agreed key. */
2551    await publicInitFunc(srcKeyAliasSecond, HuksOptions);
2552    HuksOptions.inData = exportKeyFrist;
2553    await publicUpdateFunc(handle, HuksOptions);
2554    await publicFinishFunc(handle, finishOptionsSecond);
2555
2556
2557    await publicDeleteKeyFunc(srcKeyAliasFirst, HuksOptions);
2558    await publicDeleteKeyFunc(srcKeyAliasSecond, HuksOptions);
2559}
2560
2561@Entry
2562@Component
2563struct Index {
2564    build() {
2565        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
2566            Button() {
2567                Text('testAgree')
2568                    .fontSize(30)
2569                    .fontWeight(FontWeight.Bold)
2570            }.type(ButtonType.Capsule)
2571            .margin({
2572                top: 20
2573            })
2574            .backgroundColor('#0D9FFB')
2575            .onClick(()=>{
2576              testAgree();
2577            })
2578        }
2579        .width('100%')
2580        .height('100%')
2581    }
2582}
2583```
2584
2585### Key Derivation
2586
2587Derive one or more keys from a key.
2588
2589The development procedure is as follows:
2590
25911. Generate a key.
25922. Derive a key.
2593
2594**Supported key types**:
2595
2596The **HksInit()** and **HksFinish()** APIs have requirements on **paramSet**. The **HksUpdate()** API has no requirements on **paramSet**.
2597
2598Requirements of **HksInit()** for **paramSet**:
2599
2600| HUKS_TAG_ALGORITHM                                           | HUKS_TAG_PURPOSE        | HUKS_TAG_DIGEST                                            | HUKS_TAG_DERIVE_KEY_SIZE |
2601| ------------------------------------------------------------ | ----------------------- | ---------------------------------------------------------- | ------------------------ |
2602| HUKS_ALG_HKDF (supported key lengths: HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256)| HUKS_KEY_PURPOSE_DERIVE | HUKS_DIGEST_SHA256 HUKS_DIGEST_SHA384  HUKS_DIGEST_SHA512  | Mandatory                |
2603| HUKS_ALG_PBKDF2 (supported key lengths: HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256)| HUKS_KEY_PURPOSE_DERIVE | HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Mandatory                |
2604
2605Requirements of **HksFinish()** for **paramSet**:
2606
2607The derived key is used as a symmetric key.
2608
2609| HUKS_TAG_KEY_STORAGE_FLAG      | HUKS_TAG_KEY_ALIAS | HUKS_TAG_IS_KEY_ALIAS | HUKS_TAG_ALGORITHM | HUKS_TAG_KEY_SIZE                                            | HUKS_TAG_PURPOSE                                   | HUKS_TAG_PADDING                      | HUKS_TAG_DIGEST                                              | HUKS_TAG_BLOCK_MODE                         |
2610| ------------------------------ | ------------------ | --------------------- | ------------------ | ------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------ | ------------------------------------------- |
2611| **HUKS_STORAGE_TEMP** or not set| Not required            | TRUE                  | Not required            | Not required                                                      | Not required                                            | Not required                               | Not required                                                      | Not required                                     |
2612| HUKS_STORAGE_PERSISTENT        | (Mandatory) Maximum 64 bytes.| TRUE                  | HUKS_ALG_AES       | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_PADDING_NONE, HUKS_PADDING_PKCS7| Optional                                                  | HUKS_MODE_CBC  HUKS_MODE_ECB                |
2613| HUKS_STORAGE_PERSISTENT        | (Mandatory) Maximum 64 bytes.| TRUE                  | HUKS_ALG_AES       | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_ENCRYPT or HUKS_KEY_PURPOSE_DECRYPT| HUKS_PADDING_NONE                     | Optional                                                  | HUKS_MODE_CCM, HUKS_MODE_GCM, HUKS_MODE_CTR|
2614| HUKS_STORAGE_PERSISTENT        | (Mandatory) Maximum 64 bytes.| TRUE                  | HUKS_ALG_AES       | HUKS_AES_KEY_SIZE_128, HUKS_AES_KEY_SIZE_192, HUKS_AES_KEY_SIZE_256| HUKS_KEY_PURPOSE_DERIVE                            | Optional                           | HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512  | Optional                                 |
2615| HUKS_STORAGE_PERSISTENT        | (Mandatory) Maximum 64 bytes.| TRUE                  | HUKS_ALG_HMAC      | Multiple of 8, in bits                                        | HUKS_KEY_PURPOSE_MAC                               | Optional                           | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Optional                                 |
2616
2617> **NOTE**<br>
2618>
2619> The length of the derived key (converted into bits) must be greater than or equal to the selected **HUKS_TAG_KEY_SIZE**.
2620>
2621> The key alias cannot exceed 64 bytes.
2622
2623Before you get started, understand the following variables:
2624
2625| Parameter       | Type       | Mandatory| Description            |
2626| ------------- | ----------- | ---- | ---------------- |
2627| srcKeyAlias   | string      | Yes  | Alias of the key generated.  |
2628| huksOptions   | HuksOptions | Yes  | Parameters for generating the key.|
2629| finishOptions | HuksOptions | Yes  | Parameters for deriving a key.|
2630
2631For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
2632
2633**Example**
2634
2635```ts
2636/*The derive() operation supports HKDF and pbdkf keys.
2637 *
2638 * The following uses the Promise() operation of an HKDF256 key as an example.
2639 */
2640import huks from '@ohos.security.huks';
2641
2642function StringToUint8Array(str) {
2643    let arr = [];
2644    for (let i = 0, j = str.length; i < j; ++i) {
2645        arr.push(str.charCodeAt(i));
2646    }
2647    return new Uint8Array(arr);
2648}
2649
2650async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2651    console.info(`enter callback generateKeyItem`);
2652    try {
2653        await generateKeyItem(keyAlias, huksOptions)
2654            .then((data) => {
2655                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
2656            })
2657            .catch(error => {
2658                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
2659            });
2660    } catch (error) {
2661        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
2662    }
2663}
2664
2665function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
2666    return new Promise((resolve, reject) => {
2667        try {
2668            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
2669                if (error) {
2670                    reject(error);
2671                } else {
2672                    resolve(data);
2673                }
2674            });
2675        } catch (error) {
2676            throw(error);
2677        }
2678    });
2679}
2680
2681async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2682    console.info(`enter promise doInit`);
2683    try {
2684        await huks.initSession(keyAlias, huksOptions)
2685            .then ((data) => {
2686                console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
2687                handle = data.handle;
2688            })
2689            .catch(error => {
2690                console.error(`promise: doInit key failed, code: ${error.code}, msg: ${error.message}`);
2691            });
2692    } catch (error) {
2693        console.error(`promise: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
2694    }
2695}
2696
2697async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
2698    console.info(`enter callback doUpdate`);
2699    try {
2700        await updateSession(handle, huksOptions)
2701            .then ((data) => {
2702                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
2703            })
2704            .catch(error => {
2705                console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
2706            });
2707    } catch (error) {
2708        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
2709    }
2710}
2711
2712function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
2713    return new Promise((resolve, reject) => {
2714        try {
2715            huks.updateSession(handle, huksOptions, function (error, data) {
2716                if (error) {
2717                    reject(error);
2718                } else {
2719                    resolve(data);
2720                }
2721            });
2722        } catch (error) {
2723            throw(error);
2724        }
2725    });
2726}
2727
2728async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
2729    console.info(`enter callback doFinish`);
2730    try {
2731        await finishSession(handle, huksOptions)
2732            .then ((data) => {
2733                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
2734            })
2735            .catch(error => {
2736                console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
2737            });
2738    } catch (error) {
2739        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
2740    }
2741}
2742
2743function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
2744    return new Promise((resolve, reject) => {
2745        try {
2746            huks.finishSession(handle, huksOptions, function (error, data) {
2747                if (error) {
2748                    reject(error);
2749                } else {
2750                    resolve(data);
2751                }
2752            });
2753        } catch (error) {
2754            throw(error);
2755        }
2756    });
2757}
2758
2759async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2760    console.info(`enter callback deleteKeyItem`);
2761    try {
2762        await deleteKeyItem(keyAlias, huksOptions)
2763            .then ((data) => {
2764                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
2765            })
2766            .catch(error => {
2767                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
2768            });
2769    } catch (error) {
2770        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
2771    }
2772}
2773
2774function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
2775    return new Promise((resolve, reject) => {
2776        try {
2777            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
2778                if (error) {
2779                    reject(error);
2780                } else {
2781                    resolve(data);
2782                }
2783            });
2784        } catch (error) {
2785            throw(error);
2786        }
2787    });
2788}
2789
2790let deriveHkdfInData = "deriveHkdfTestIndata";
2791let srcKeyAlias = "deriveHkdfKeyAlias";
2792let handle;
2793let HuksKeyDeriveKeySize = 32;
2794
2795async function testDerive() {
2796    /* Configure the parameters for generating the key. */
2797    let properties = new Array();
2798    properties[0] = {
2799        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2800        value: huks.HuksKeyAlg.HUKS_ALG_AES,
2801    }
2802    properties[1] = {
2803        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
2804        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DERIVE,
2805    }
2806    properties[2] = {
2807        tag: huks.HuksTag.HUKS_TAG_DIGEST,
2808        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256,
2809    }
2810    properties[3] = {
2811        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2812        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
2813    }
2814    let huksOptions = {
2815        properties: properties,
2816        inData: new Uint8Array(new Array())
2817    }
2818
2819    /* Generate a key. */
2820    await publicGenKeyFunc(srcKeyAlias, huksOptions);
2821
2822    /* Modify the parameter set for init(). */
2823    huksOptions.properties.splice(0, 1, {
2824        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2825        value: huks.HuksKeyAlg.HUKS_ALG_HKDF,
2826    });
2827    huksOptions.properties.splice(3, 1, {
2828        tag: huks.HuksTag.HUKS_TAG_DERIVE_KEY_SIZE,
2829        value: HuksKeyDeriveKeySize,
2830    });
2831
2832    let finishProperties = new Array();
2833    finishProperties[0] = {
2834        tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG,
2835        value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT,
2836    }
2837    finishProperties[1] = {
2838        tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS,
2839        value: true,
2840    }
2841    finishProperties[2] = {
2842        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2843        value: huks.HuksKeyAlg.HUKS_ALG_AES,
2844    }
2845    finishProperties[3] = {
2846        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2847        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
2848    }
2849    finishProperties[4] = {
2850        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
2851        value:
2852        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
2853        huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
2854    }
2855    finishProperties[5] = {
2856        tag: huks.HuksTag.HUKS_TAG_DIGEST,
2857        value: huks.HuksKeyDigest.HUKS_DIGEST_NONE,
2858    }
2859    finishProperties[6] = {
2860        tag: huks.HuksTag.HUKS_TAG_KEY_ALIAS,
2861        value: StringToUint8Array(srcKeyAlias),
2862    }
2863    finishProperties[7] = {
2864        tag: huks.HuksTag.HUKS_TAG_PADDING,
2865        value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
2866    }
2867    finishProperties[8] = {
2868        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
2869        value: huks.HuksCipherMode.HUKS_MODE_ECB,
2870    }
2871    let finishOptions = {
2872        properties: finishProperties,
2873        inData: new Uint8Array(new Array())
2874    }
2875
2876    /* Derive a key. */
2877    await publicInitFunc(srcKeyAlias, huksOptions);
2878
2879    huksOptions.inData = StringToUint8Array(deriveHkdfInData);
2880    await publicUpdateFunc(handle, huksOptions);
2881    await publicFinishFunc(handle, finishOptions);
2882
2883    huksOptions.properties.splice(0, 1, {
2884        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
2885        value: huks.HuksKeyAlg.HUKS_ALG_AES,
2886    });
2887    huksOptions.properties.splice(3, 1, {
2888        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
2889        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128,
2890    });
2891
2892    await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
2893}
2894
2895@Entry
2896@Component
2897struct Index {
2898    build() {
2899        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
2900            Button() {
2901                Text('testDerive')
2902                    .fontSize(30)
2903                    .fontWeight(FontWeight.Bold)
2904            }.type(ButtonType.Capsule)
2905            .margin({
2906                top: 20
2907            })
2908            .backgroundColor('#0D9FFB')
2909            .onClick(()=>{
2910                testDerive();
2911            })
2912        }
2913        .width('100%')
2914        .height('100%')
2915    }
2916}
2917```
2918
2919### Key MAC
2920
2921A message authentication code (MAC) is a hash-based value used for authenticating a message. It is used to check whether the message comes from the stated sender and has not been changed.
2922
2923The development procedure is as follows:
2924
29251. Generate a key.
29262. Generate a MAC.
2927
2928**Supported key types**:
2929
2930Only **HksInit()** has requirements on parameters in **paramSet**. The other Init-Update-Finish APIs have no requirements on **paramSet**.
2931
2932| HUKS_TAG_ALGORITHM | HUKS_TAG_KEY_SIZE | HUKS_TAG_PURPOSE    | HUKS_TAG_DIGEST                                              | HUKS_TAG_PADDING | HUKS_TAG_BLOCK_MODE |
2933| ------------ | ---------- | ------------------- | ------------------------------------------------------------ | ---------- | ---------- |
2934| HUKS_ALG_HMAC | Optional| HUKS_KEY_PURPOSE_MAC | HUKS_DIGEST_SHA1, HUKS_DIGEST_SHA224, HUKS_DIGEST_SHA256, HUKS_DIGEST_SHA384, HUKS_DIGEST_SHA512| Optional| Optional|
2935| HUKS_ALG_SM3 | Optional| HUKS_KEY_PURPOSE_MAC | HUKS_DIGEST_SM3                                              | Optional| Optional|
2936
2937> **NOTE**<br>
2938>
2939> The key alias cannot exceed 64 bytes.
2940
2941Before you get started, understand the following variables:
2942
2943| Parameter     | Type       | Mandatory| Description          |
2944| ----------- | ----------- | ---- | -------------- |
2945| srcKeyAlias | string      | Yes  | Alias of the key generated.|
2946| huksOptions | HuksOptions | Yes  | Key parameter set.  |
2947
2948For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
2949
2950**Example**
2951
2952```ts
2953/*The mac() operation supports HMAC and SM3 keys.
2954 *
2955 * The following uses the Promise() operation of an SM3 256-bit key as an example.
2956 */
2957import huks from '@ohos.security.huks';
2958
2959function StringToUint8Array(str) {
2960    let arr = [];
2961    for (let i = 0, j = str.length; i < j; ++i) {
2962        arr.push(str.charCodeAt(i));
2963    }
2964    return new Uint8Array(arr);
2965}
2966
2967async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2968    console.info(`enter callback generateKeyItem`);
2969    try {
2970        await generateKeyItem(keyAlias, huksOptions)
2971            .then((data) => {
2972                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
2973            })
2974            .catch(error => {
2975                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
2976            });
2977    } catch (error) {
2978        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
2979    }
2980}
2981
2982function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
2983    return new Promise((resolve, reject) => {
2984        try {
2985            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
2986                if (error) {
2987                    reject(error);
2988                } else {
2989                    resolve(data);
2990                }
2991            });
2992        } catch (error) {
2993            throw(error);
2994        }
2995    });
2996}
2997
2998async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
2999    console.info(`enter callback doInit`);
3000    try {
3001        await initSession(keyAlias, huksOptions)
3002            .then ((data) => {
3003                console.info(`callback1: doInit success, data = ${JSON.stringify(data)}`);
3004                handle = data.handle;
3005            })
3006            .catch((error) => {
3007                console.error(`callback1: doInit failed, code: ${error.code}, msg: ${error.message}`);
3008            });
3009    } catch (error) {
3010        console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`);
3011    }
3012}
3013
3014function initSession(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksSessionHandle> {
3015    return new Promise((resolve, reject) => {
3016        try {
3017            huks.initSession(keyAlias, huksOptions, function (error, data) {
3018                if (error) {
3019                    reject(error);
3020                } else {
3021                    resolve(data);
3022                }
3023            });
3024        } catch (error) {
3025            throw(error);
3026        }
3027    });
3028}
3029
3030async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
3031    console.info(`enter callback doUpdate`);
3032    try {
3033        await updateSession(handle, huksOptions)
3034            .then ((data) => {
3035                console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`);
3036            })
3037            .catch(error => {
3038                console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`);
3039            });
3040    } catch (error) {
3041        console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`);
3042    }
3043}
3044
3045function updateSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
3046    return new Promise((resolve, reject) => {
3047        try {
3048            huks.updateSession(handle, huksOptions, function (error, data) {
3049                if (error) {
3050                    reject(error);
3051                } else {
3052                    resolve(data);
3053                }
3054            });
3055        } catch (error) {
3056            throw(error);
3057        }
3058    });
3059}
3060
3061async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
3062    console.info(`enter callback doFinish`);
3063    try {
3064        await finishSession(handle, huksOptions)
3065            .then ((data) => {
3066                console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`);
3067            })
3068            .catch(error => {
3069                console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`);
3070            });
3071    } catch (error) {
3072        console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`);
3073    }
3074}
3075
3076function finishSession(handle:number, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult> {
3077    return new Promise((resolve, reject) => {
3078        try {
3079            huks.finishSession(handle, huksOptions, function (error, data) {
3080                if (error) {
3081                    reject(error);
3082                } else {
3083                    resolve(data);
3084                }
3085            });
3086        } catch (error) {
3087            throw(error);
3088        }
3089    });
3090}
3091
3092async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
3093    console.info(`enter callback deleteKeyItem`);
3094    try {
3095        await deleteKeyItem(keyAlias, huksOptions)
3096            .then ((data) => {
3097                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
3098            })
3099            .catch(error => {
3100                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
3101            });
3102    } catch (error) {
3103        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
3104    }
3105}
3106
3107function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
3108    return new Promise((resolve, reject) => {
3109        try {
3110            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
3111                if (error) {
3112                    reject(error);
3113                } else {
3114                    resolve(data);
3115                }
3116            });
3117        } catch (error) {
3118            throw(error);
3119        }
3120    });
3121}
3122
3123let srcKeyAlias = "sm3KeyAlias";
3124let hmacInData = 'sm3TestIndata';
3125let handle;
3126
3127async function testMac() {
3128    /* Configure the parameters for generating the key. */
3129    let properties = new Array();
3130    properties[0] = {
3131        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
3132        value: huks.HuksKeyAlg.HUKS_ALG_SM3,
3133    }
3134    properties[1] = {
3135        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
3136        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_MAC,
3137    }
3138    properties[2] = {
3139        tag: huks.HuksTag.HUKS_TAG_DIGEST,
3140        value: huks.HuksKeyDigest.HUKS_DIGEST_SM3,
3141    }
3142    properties[3] = {
3143        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
3144        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
3145    }
3146    let huksOptions = {
3147        properties:properties,
3148        inData:new Uint8Array(new Array())
3149    }
3150
3151    /* Generate a key. */
3152    await publicGenKeyFunc(srcKeyAlias, huksOptions);
3153
3154    /* Modify the parameter set for init() and perform the mac operation. */
3155    huksOptions.properties.splice(3, 3);
3156    await publicInitFunc(srcKeyAlias, huksOptions);
3157    huksOptions.inData = StringToUint8Array(hmacInData);
3158    await publicUpdateFunc(handle, huksOptions);
3159    huksOptions.inData = new Uint8Array(new Array());
3160    await publicFinishFunc(handle, huksOptions);
3161
3162    huksOptions.properties.splice(1, 0, {
3163        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
3164        value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256,
3165    });
3166    await publicDeleteKeyFunc(srcKeyAlias, huksOptions);
3167}
3168
3169@Entry
3170@Component
3171struct Index {
3172    build() {
3173        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
3174            Button() {
3175                Text('testMac')
3176                    .fontSize(30)
3177                    .fontWeight(FontWeight.Bold)
3178            }.type(ButtonType.Capsule)
3179            .margin({
3180                top: 20
3181            })
3182            .backgroundColor('#0D9FFB')
3183            .onClick(()=>{
3184                testMac();
3185            })
3186        }
3187        .width('100%')
3188        .height('100%')
3189    }
3190}
3191```
3192
3193### AttestID
3194
3195After an application generates an asymmetric key, the certificate chain can be obtained through ID attestation. ID attestation supports the following device: brand, device, product, serial number, IMEI, MEID, manufacturer, model, SOC ID, and UDID.
3196
3197The application can also obtain the certificate chain through key attestation.
3198
3199ID attestation and key attestation are available only for devices in a trusted execution Environment (TEE).
3200
3201The development procedure is as follows:
3202
32031. Generate a certificate.
32042. Obtain certificate information.
3205
3206**Supported key types**:
3207
3208RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, ECC224, ECC256, ECC384, ECC521, X25519
3209
3210> **NOTE**<br>
3211>
3212> The key alias cannot exceed 64 bytes.
3213
3214Before you get started, understand the following variables:
3215
3216| Parameter  | Type       | Mandatory| Description                                |
3217| -------- | ----------- | ---- | ------------------------------------ |
3218| keyAlias | string      | Yes  | Alias of the key. The certificate to be obtained stores the key.|
3219| options  | HuksOptions | Yes  | Parameters and data required for obtaining the certificate.  |
3220
3221For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
3222
3223**Example**
3224
3225```ts
3226/* The following is an example of ID attestation. */
3227import huks from '@ohos.security.huks';
3228
3229function StringToUint8Array(str) {
3230    let arr = [];
3231    for (let i = 0, j = str.length; i < j; ++i) {
3232        arr.push(str.charCodeAt(i));
3233    }
3234    return new Uint8Array(arr);
3235}
3236
3237async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
3238    console.info(`enter callback generateKeyItem`);
3239    try {
3240        await generateKeyItem(keyAlias, huksOptions)
3241            .then((data) => {
3242                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
3243            })
3244            .catch(error => {
3245                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
3246            });
3247    } catch (error) {
3248        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
3249    }
3250}
3251
3252function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
3253    return new Promise((resolve, reject) => {
3254        try {
3255            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
3256                if (error) {
3257                    reject(error);
3258                } else {
3259                    resolve(data);
3260                }
3261            });
3262        } catch (error) {
3263            throw(error);
3264        }
3265    });
3266}
3267
3268async function publicAttestKey(keyAlias:string, huksOptions:huks.HuksOptions) {
3269    console.info(`enter callback attestKeyItem`);
3270    try {
3271        await attestKeyItem(keyAlias, huksOptions)
3272            .then ((data) => {
3273                console.info(`callback: attestKeyItem success, data = ${JSON.stringify(data)}`);
3274            })
3275            .catch(error => {
3276                console.error(`callback: attestKeyItem failed, code: ${error.code}, msg: ${error.message}`);
3277            });
3278    } catch (error) {
3279        console.error(`callback: attestKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
3280    }
3281}
3282
3283function attestKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult>{
3284    return new Promise((resolve, reject) => {
3285        try {
3286            huks.attestKeyItem(keyAlias, huksOptions, function (error, data) {
3287                if (error) {
3288                    reject(error);
3289                } else {
3290                    resolve(data);
3291                }
3292            });
3293        } catch (error) {
3294            throw(error);
3295        }
3296    });
3297}
3298
3299async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
3300    console.info(`enter callback deleteKeyItem`);
3301    try {
3302        await deleteKeyItem(keyAlias, huksOptions)
3303            .then ((data) => {
3304                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
3305            })
3306            .catch(error => {
3307                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
3308            });
3309    } catch (error) {
3310        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
3311    }
3312}
3313
3314function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
3315    return new Promise((resolve, reject) => {
3316        try {
3317            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
3318                if (error) {
3319                    reject(error);
3320                } else {
3321                    resolve(data);
3322                }
3323            });
3324        } catch (error) {
3325            throw(error);
3326        }
3327    });
3328}
3329
3330let securityLevel = StringToUint8Array('sec_level');
3331let challenge = StringToUint8Array('challenge_data');
3332let versionInfo = StringToUint8Array('version_info');
3333let udid = StringToUint8Array('udid');
3334let serial = StringToUint8Array('serial');
3335let deviceId = StringToUint8Array('device_id');
3336let idAliasString = "id attest";
3337
3338async function testAttestId() {
3339    let aliasString = idAliasString;
3340    let aliasUint8 = StringToUint8Array(aliasString);
3341
3342    /* Configure parameters and generate a key. */
3343    let properties = new Array();
3344    properties[0] = {
3345        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
3346        value: huks.HuksKeyAlg.HUKS_ALG_RSA
3347    };
3348    properties[1] = {
3349        tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG,
3350        value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT
3351    };
3352    properties[2] = {
3353        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
3354        value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048
3355    };
3356    properties[3] = {
3357        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
3358        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY
3359    };
3360    properties[4] = {
3361        tag: huks.HuksTag.HUKS_TAG_DIGEST,
3362        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
3363    };
3364    properties[5] = {
3365        tag: huks.HuksTag.HUKS_TAG_PADDING,
3366        value: huks.HuksKeyPadding.HUKS_PADDING_PSS
3367    };
3368    properties[6] = {
3369        tag: huks.HuksTag.HUKS_TAG_KEY_GENERATE_TYPE,
3370        value: huks.HuksKeyGenerateType.HUKS_KEY_GENERATE_TYPE_DEFAULT
3371    };
3372    properties[7] = {
3373        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
3374        value: huks.HuksCipherMode.HUKS_MODE_ECB
3375    };
3376    let options = {
3377        properties: properties
3378    };
3379    await publicGenKeyFunc(aliasString, options);
3380
3381    /* Configure the certificate parameter set. */
3382    let attestProperties = new Array();
3383    attestProperties[0] = {
3384        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO,
3385        value: securityLevel
3386    };
3387    attestProperties[1] = {
3388        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_CHALLENGE,
3389        value: challenge
3390    };
3391    attestProperties[2] = {
3392        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_VERSION_INFO,
3393        value: versionInfo
3394    };
3395    attestProperties[3] = {
3396        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_ALIAS,
3397        value: aliasUint8
3398    };
3399    attestProperties[4] = {
3400        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_UDID,
3401        value: udid
3402    };
3403    attestProperties[5] = {
3404        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SERIAL,
3405        value: serial
3406    };
3407    attestProperties[6] = {
3408        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_DEVICE,
3409        value: deviceId
3410    };
3411    let huksOptions = {
3412        properties: attestProperties
3413    };
3414
3415    await publicAttestKey(aliasString, huksOptions);
3416
3417    await publicDeleteKeyFunc(aliasString, options);
3418}
3419
3420@Entry
3421@Component
3422struct Index {
3423    build() {
3424        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
3425            Button() {
3426                Text('testAttestId')
3427                    .fontSize(30)
3428                    .fontWeight(FontWeight.Bold)
3429            }.type(ButtonType.Capsule)
3430            .margin({
3431                top: 20
3432            })
3433            .backgroundColor('#0D9FFB')
3434            .onClick(()=>{
3435                testAttestId();
3436            })
3437        }
3438        .width('100%')
3439        .height('100%')
3440    }
3441}
3442```
3443
3444### AttestKey
3445
3446After an application generates an asymmetric key, the certificate chain can be obtained by key attestation. You can also use ID attestation to obtain the certificate chain. The public certificate contains information such as the device ID.
3447
3448ID attestation and key attestation are available only for devices in a trusted execution Environment (TEE).
3449
3450The development procedure is as follows:
3451
34521. Generate a certificate.
34532. Obtain certificate information.
3454
3455**Supported key types**:
3456
3457RSA512, RSA768, RSA1024, RSA2048, RSA3072, RSA4096, ECC224, ECC256, ECC384, ECC521, X25519
3458
3459> **NOTE**<br>
3460>
3461> The key alias cannot exceed 64 bytes.
3462
3463Before you get started, understand the following variables:
3464
3465| Parameter  | Type       | Mandatory| Description                                |
3466| -------- | ----------- | ---- | ------------------------------------ |
3467| keyAlias | string      | Yes  | Alias of the key. The certificate to be obtained stores the key.|
3468| options  | HuksOptions | Yes  | Parameters and data required for obtaining the certificate.  |
3469
3470For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md).
3471
3472**Example**
3473
3474```ts
3475/* The following is an example of AttestKey. */
3476import huks from '@ohos.security.huks';
3477
3478function StringToUint8Array(str) {
3479    let arr = [];
3480    for (let i = 0, j = str.length; i < j; ++i) {
3481        arr.push(str.charCodeAt(i));
3482    }
3483    return new Uint8Array(arr);
3484}
3485
3486async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
3487    console.info(`enter callback generateKeyItem`);
3488    try {
3489        await generateKeyItem(keyAlias, huksOptions)
3490            .then((data) => {
3491                console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`);
3492            })
3493            .catch(error => {
3494                console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`);
3495            });
3496    } catch (error) {
3497        console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
3498    }
3499}
3500
3501function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
3502    return new Promise((resolve, reject) => {
3503        try {
3504            huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
3505                if (error) {
3506                    reject(error);
3507                } else {
3508                    resolve(data);
3509                }
3510            });
3511        } catch (error) {
3512            throw(error);
3513        }
3514    });
3515}
3516
3517async function publicAttestKey(keyAlias:string, huksOptions:huks.HuksOptions) {
3518    console.info(`enter callback attestKeyItem`);
3519    try {
3520        await attestKeyItem(keyAlias, huksOptions)
3521            .then ((data) => {
3522                console.info(`callback: attestKeyItem success, data = ${JSON.stringify(data)}`);
3523            })
3524            .catch(error => {
3525                console.error(`callback: attestKeyItem failed, code: ${error.code}, msg: ${error.message}`);
3526            });
3527    } catch (error) {
3528        console.error(`callback: attestKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
3529    }
3530}
3531
3532function attestKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) : Promise<huks.HuksReturnResult>{
3533    return new Promise((resolve, reject) => {
3534        try {
3535            huks.attestKeyItem(keyAlias, huksOptions, function (error, data) {
3536                if (error) {
3537                    reject(error);
3538                } else {
3539                    resolve(data);
3540                }
3541            });
3542        } catch (error) {
3543            throw(error);
3544        }
3545    });
3546}
3547
3548async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
3549    console.info(`enter callback deleteKeyItem`);
3550    try {
3551        await deleteKeyItem(keyAlias, huksOptions)
3552            .then ((data) => {
3553                console.info(`callback: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
3554            })
3555            .catch(error => {
3556                console.error(`callback: deleteKeyItem failed, code: ${error.code}, msg: ${error.message}`);
3557            });
3558    } catch (error) {
3559        console.error(`callback: deleteKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`);
3560    }
3561}
3562
3563function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions) {
3564    return new Promise((resolve, reject) => {
3565        try {
3566            huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
3567                if (error) {
3568                    reject(error);
3569                } else {
3570                    resolve(data);
3571                }
3572            });
3573        } catch (error) {
3574            throw(error);
3575        }
3576    });
3577}
3578
3579let securityLevel = StringToUint8Array('sec_level');
3580let challenge = StringToUint8Array('challenge_data');
3581let versionInfo = StringToUint8Array('version_info');
3582let keyAliasString = "key attest";
3583
3584async function testAttestKey() {
3585    let aliasString = keyAliasString;
3586    let aliasUint8 = StringToUint8Array(aliasString);
3587
3588    let properties = new Array();
3589    properties[0] = {
3590        tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
3591        value: huks.HuksKeyAlg.HUKS_ALG_RSA
3592    };
3593    properties[1] = {
3594        tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG,
3595        value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT
3596    };
3597    properties[2] = {
3598        tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
3599        value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048
3600    };
3601    properties[3] = {
3602        tag: huks.HuksTag.HUKS_TAG_PURPOSE,
3603        value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY
3604    };
3605    properties[4] = {
3606        tag: huks.HuksTag.HUKS_TAG_DIGEST,
3607        value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
3608    };
3609    properties[5] = {
3610        tag: huks.HuksTag.HUKS_TAG_PADDING,
3611        value: huks.HuksKeyPadding.HUKS_PADDING_PSS
3612    };
3613    properties[6] = {
3614        tag: huks.HuksTag.HUKS_TAG_KEY_GENERATE_TYPE,
3615        value: huks.HuksKeyGenerateType.HUKS_KEY_GENERATE_TYPE_DEFAULT
3616    };
3617    properties[7] = {
3618        tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
3619        value: huks.HuksCipherMode.HUKS_MODE_ECB
3620    };
3621    let options = {
3622        properties: properties
3623    };
3624    await publicGenKeyFunc(aliasString, options);
3625
3626    /* Configure the certificate parameter set. */
3627    let attestProperties = new Array();
3628    attestProperties[0] = {
3629        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO,
3630        value: securityLevel
3631    };
3632    attestProperties[1] = {
3633        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_CHALLENGE,
3634        value: challenge
3635    };
3636    attestProperties[2] = {
3637        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_VERSION_INFO,
3638        value: versionInfo
3639    };
3640    attestProperties[3] = {
3641        tag: huks.HuksTag.HUKS_TAG_ATTESTATION_ID_ALIAS,
3642        value: aliasUint8
3643    };
3644    let huksOptions = {
3645        properties: attestProperties
3646    };
3647
3648    await publicAttestKey(aliasString, huksOptions);
3649
3650    await publicDeleteKeyFunc(aliasString, options);
3651}
3652
3653@Entry
3654@Component
3655struct Index {
3656    build() {
3657        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
3658            Button() {
3659                Text('testAttestKey')
3660                    .fontSize(30)
3661                    .fontWeight(FontWeight.Bold)
3662            }.type(ButtonType.Capsule)
3663            .margin({
3664                top: 20
3665            })
3666            .backgroundColor('#0D9FFB')
3667            .onClick(()=>{
3668                testAttestKey();
3669            })
3670        }
3671        .width('100%')
3672        .height('100%')
3673    }
3674}
3675```
3676