1e41f4b71Sopenharmony_ci# Importing a Key in Ciphertext (ArkTS)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ciThis topic walks you through on how to import an ECDH key pair. However, the example does not cover the operations such as [key generation](huks-key-generation-overview.md) and [key agreement](huks-key-agreement-overview.md) of the service side.
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciFor details about the scenarios and supported algorithm specifications, see [Supported Algorithms](huks-key-import-overview.md#supported-algorithms).
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci## How to Develop
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci1. Convert the key to be imported from device A (device from which the key is imported) to [HUKS key material format](huks-concepts.md#key material format) **To_Import_Key**. (This step applies only to asymmetric key pairs. If the key to be imported is a symmetric key, skip over this step.)
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci2. Generate an asymmetric key pair **Wrapping_Key** (public key **Wrapping_Pk** and private key **Wrapping_Sk**) with the purpose of **HUKS_KEY_PURPOSE_UNWRAP** for device B (device to which the key is imported), and export the public key **Wrapping_Pk** of **Wrapping_Key** and save it. The asymmetric key pair **Wrapping_Key** is used for key agreement in the encrypted import process.
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci3. Use the same algorithm to generate an asymmetric key pair **Caller_Key** (public key **Caller_Pk** and private key **Caller_Sk**) with the purpose of **HUKS_KEY_PURPOSE_UNWRAP** for device A, and export the public key **Caller_Pk** of **Caller_Key** and save it. The asymmetric key pair **Caller_Key** is used for key agreement in the encrypted import process.
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci4. Generate a symmetric key **Caller_Kek** for device A. This key is used to encrypt **To_Import_Key**.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci5. Perform key agreement with the private key **Caller_Sk** in **Caller_Key** of device A and the public key **Wrapping_Pk** in **Wrapping_Key** of device B to yield a **Shared_Key**.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci6. Use **Caller_Kek** to encrypt **To_Import_Key** of device A and generate **To_Import_Key_Enc**.
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci7. Use **Shared_Key** to encrypt **Caller_Kek** of device A and generate **Caller_Kek_Enc**.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci8. Encapsulate the key material **Caller_Pk**, **Caller_Kek_Enc**, and **To_Import_Key_Enc** of device A, and sends it to device B. For details about the format of the key material to be imported, see [Key Material Format for Encrypted Import](huks-key-import-overview.md#key-material-format-for-encrypted-import).
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci9. Import the encrypted key material to device B.
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci10. Delete the intermediate keys (keys used for encrypting the key to import) from devices A and B.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci```ts
33e41f4b71Sopenharmony_ciimport { huks } from '@kit.UniversalKeystoreKit';
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_cilet IV = '0000000000000000';
36e41f4b71Sopenharmony_cilet AAD = "abababababababab";
37e41f4b71Sopenharmony_cilet NONCE = "hahahahahaha";
38e41f4b71Sopenharmony_cilet TAG_SIZE = 16;
39e41f4b71Sopenharmony_cilet FILED_LENGTH = 4;
40e41f4b71Sopenharmony_cilet importedAes192PlainKey = "The aes192 key to import";
41e41f4b71Sopenharmony_cilet callerAes256Kek = "The is kek to encrypt aes192 key";
42e41f4b71Sopenharmony_cilet callerKeyAlias = "test_caller_key_ecdh_aes192";
43e41f4b71Sopenharmony_cilet callerKekAliasAes256 = "test_caller_kek_ecdh_aes256";
44e41f4b71Sopenharmony_cilet callerAgreeKeyAliasAes256 = "test_caller_agree_key_ecdh_aes256";
45e41f4b71Sopenharmony_cilet importedKeyAliasAes192 = "test_import_key_ecdh_aes192";
46e41f4b71Sopenharmony_cilet huksPubKey: Uint8Array;
47e41f4b71Sopenharmony_cilet callerSelfPublicKey: Uint8Array;
48e41f4b71Sopenharmony_cilet outSharedKey: Uint8Array;
49e41f4b71Sopenharmony_cilet outPlainKeyEncData: Uint8Array;
50e41f4b71Sopenharmony_cilet outKekEncData: Uint8Array;
51e41f4b71Sopenharmony_cilet outKekEncTag: Uint8Array;
52e41f4b71Sopenharmony_cilet outAgreeKeyEncTag: Uint8Array;
53e41f4b71Sopenharmony_cilet mask = [0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000];
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_cifunction subUint8ArrayOf(arrayBuf: Uint8Array, start: number, end: number) {
56e41f4b71Sopenharmony_ci  let arr: number[] = [];
57e41f4b71Sopenharmony_ci  for (let i = start; i < end && i < arrayBuf.length; ++i) {
58e41f4b71Sopenharmony_ci    arr.push(arrayBuf[i]);
59e41f4b71Sopenharmony_ci  }
60e41f4b71Sopenharmony_ci  return new Uint8Array(arr);
61e41f4b71Sopenharmony_ci}
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_cifunction stringToUint8Array(str: string) {
64e41f4b71Sopenharmony_ci  let arr: number[] = [];
65e41f4b71Sopenharmony_ci  for (let i = 0, j = str.length; i < j; ++i) {
66e41f4b71Sopenharmony_ci    arr.push(str.charCodeAt(i));
67e41f4b71Sopenharmony_ci  }
68e41f4b71Sopenharmony_ci  return new Uint8Array(arr);
69e41f4b71Sopenharmony_ci}
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_cifunction assignLength(length: number, arrayBuf: Uint8Array, startIndex: number) {
72e41f4b71Sopenharmony_ci  let index = startIndex;
73e41f4b71Sopenharmony_ci  for (let i = 0; i < 4; i++) {
74e41f4b71Sopenharmony_ci    arrayBuf[index++] = (length & mask[i]) >> (i * 8);
75e41f4b71Sopenharmony_ci  }
76e41f4b71Sopenharmony_ci  return 4;
77e41f4b71Sopenharmony_ci}
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_cifunction assignData(data: Uint8Array, arrayBuf: Uint8Array, startIndex: number) {
80e41f4b71Sopenharmony_ci  let index = startIndex;
81e41f4b71Sopenharmony_ci  for (let i = 0; i < data.length; i++) {
82e41f4b71Sopenharmony_ci    arrayBuf[index++] = data[i];
83e41f4b71Sopenharmony_ci  }
84e41f4b71Sopenharmony_ci  return data.length;
85e41f4b71Sopenharmony_ci}
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_cilet genWrappingKeyParams: huks.HuksOptions = {
88e41f4b71Sopenharmony_ci  properties: new Array<huks.HuksParam>(
89e41f4b71Sopenharmony_ci    {
90e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
91e41f4b71Sopenharmony_ci      value: huks.HuksKeyAlg.HUKS_ALG_ECC
92e41f4b71Sopenharmony_ci    },
93e41f4b71Sopenharmony_ci    {
94e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
95e41f4b71Sopenharmony_ci      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_UNWRAP
96e41f4b71Sopenharmony_ci    },
97e41f4b71Sopenharmony_ci    {
98e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
99e41f4b71Sopenharmony_ci      value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256
100e41f4b71Sopenharmony_ci    },
101e41f4b71Sopenharmony_ci    {
102e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PADDING,
103e41f4b71Sopenharmony_ci      value: huks.HuksKeyPadding.HUKS_PADDING_NONE
104e41f4b71Sopenharmony_ci    }
105e41f4b71Sopenharmony_ci  )
106e41f4b71Sopenharmony_ci}
107e41f4b71Sopenharmony_cilet genCallerEcdhParams: huks.HuksOptions = {
108e41f4b71Sopenharmony_ci  properties: new Array<huks.HuksParam>(
109e41f4b71Sopenharmony_ci    {
110e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
111e41f4b71Sopenharmony_ci      value: huks.HuksKeyAlg.HUKS_ALG_ECC
112e41f4b71Sopenharmony_ci    },
113e41f4b71Sopenharmony_ci    {
114e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
115e41f4b71Sopenharmony_ci      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE
116e41f4b71Sopenharmony_ci    },
117e41f4b71Sopenharmony_ci    {
118e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
119e41f4b71Sopenharmony_ci      value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256
120e41f4b71Sopenharmony_ci    }
121e41f4b71Sopenharmony_ci  )
122e41f4b71Sopenharmony_ci}
123e41f4b71Sopenharmony_cilet importParamsCallerKek: huks.HuksOptions = {
124e41f4b71Sopenharmony_ci  properties: new Array<huks.HuksParam>(
125e41f4b71Sopenharmony_ci    {
126e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
127e41f4b71Sopenharmony_ci      value: huks.HuksKeyAlg.HUKS_ALG_AES
128e41f4b71Sopenharmony_ci    },
129e41f4b71Sopenharmony_ci    {
130e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
131e41f4b71Sopenharmony_ci      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT
132e41f4b71Sopenharmony_ci    },
133e41f4b71Sopenharmony_ci    {
134e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
135e41f4b71Sopenharmony_ci      value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256
136e41f4b71Sopenharmony_ci    },
137e41f4b71Sopenharmony_ci    {
138e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PADDING,
139e41f4b71Sopenharmony_ci      value: huks.HuksKeyPadding.HUKS_PADDING_NONE
140e41f4b71Sopenharmony_ci    },
141e41f4b71Sopenharmony_ci    {
142e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
143e41f4b71Sopenharmony_ci      value: huks.HuksCipherMode.HUKS_MODE_GCM
144e41f4b71Sopenharmony_ci    },
145e41f4b71Sopenharmony_ci    {
146e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_DIGEST,
147e41f4b71Sopenharmony_ci      value: huks.HuksKeyDigest.HUKS_DIGEST_NONE
148e41f4b71Sopenharmony_ci    },
149e41f4b71Sopenharmony_ci    {
150e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_IV,
151e41f4b71Sopenharmony_ci      value: stringToUint8Array(IV)
152e41f4b71Sopenharmony_ci    }
153e41f4b71Sopenharmony_ci  ),
154e41f4b71Sopenharmony_ci  inData: stringToUint8Array(callerAes256Kek)
155e41f4b71Sopenharmony_ci}
156e41f4b71Sopenharmony_cilet importParamsAgreeKey: huks.HuksOptions = {
157e41f4b71Sopenharmony_ci  properties: new Array<huks.HuksParam>(
158e41f4b71Sopenharmony_ci    {
159e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
160e41f4b71Sopenharmony_ci      value: huks.HuksKeyAlg.HUKS_ALG_AES
161e41f4b71Sopenharmony_ci    },
162e41f4b71Sopenharmony_ci    {
163e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
164e41f4b71Sopenharmony_ci      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT
165e41f4b71Sopenharmony_ci    },
166e41f4b71Sopenharmony_ci    {
167e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
168e41f4b71Sopenharmony_ci      value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256
169e41f4b71Sopenharmony_ci    },
170e41f4b71Sopenharmony_ci    {
171e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PADDING,
172e41f4b71Sopenharmony_ci      value: huks.HuksKeyPadding.HUKS_PADDING_NONE
173e41f4b71Sopenharmony_ci    },
174e41f4b71Sopenharmony_ci    {
175e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
176e41f4b71Sopenharmony_ci      value: huks.HuksCipherMode.HUKS_MODE_GCM
177e41f4b71Sopenharmony_ci    },
178e41f4b71Sopenharmony_ci    {
179e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_DIGEST,
180e41f4b71Sopenharmony_ci      value: huks.HuksKeyDigest.HUKS_DIGEST_NONE
181e41f4b71Sopenharmony_ci    },
182e41f4b71Sopenharmony_ci    {
183e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_IV,
184e41f4b71Sopenharmony_ci      value: stringToUint8Array(IV)
185e41f4b71Sopenharmony_ci    }
186e41f4b71Sopenharmony_ci  ),
187e41f4b71Sopenharmony_ci}
188e41f4b71Sopenharmony_cilet callerAgreeParams: huks.HuksOptions = {
189e41f4b71Sopenharmony_ci  properties: new Array<huks.HuksParam>(
190e41f4b71Sopenharmony_ci    {
191e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
192e41f4b71Sopenharmony_ci      value: huks.HuksKeyAlg.HUKS_ALG_ECDH
193e41f4b71Sopenharmony_ci    },
194e41f4b71Sopenharmony_ci    {
195e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
196e41f4b71Sopenharmony_ci      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_AGREE
197e41f4b71Sopenharmony_ci    },
198e41f4b71Sopenharmony_ci    {
199e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
200e41f4b71Sopenharmony_ci      value: huks.HuksKeySize.HUKS_CURVE25519_KEY_SIZE_256
201e41f4b71Sopenharmony_ci    }
202e41f4b71Sopenharmony_ci  )
203e41f4b71Sopenharmony_ci}
204e41f4b71Sopenharmony_cilet encryptKeyCommonParams: huks.HuksOptions = {
205e41f4b71Sopenharmony_ci  properties: new Array<huks.HuksParam>(
206e41f4b71Sopenharmony_ci    {
207e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
208e41f4b71Sopenharmony_ci      value: huks.HuksKeyAlg.HUKS_ALG_AES
209e41f4b71Sopenharmony_ci    },
210e41f4b71Sopenharmony_ci    {
211e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
212e41f4b71Sopenharmony_ci      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT
213e41f4b71Sopenharmony_ci    },
214e41f4b71Sopenharmony_ci    {
215e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
216e41f4b71Sopenharmony_ci      value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_256
217e41f4b71Sopenharmony_ci    },
218e41f4b71Sopenharmony_ci    {
219e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PADDING,
220e41f4b71Sopenharmony_ci      value: huks.HuksKeyPadding.HUKS_PADDING_NONE
221e41f4b71Sopenharmony_ci    },
222e41f4b71Sopenharmony_ci    {
223e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
224e41f4b71Sopenharmony_ci      value: huks.HuksCipherMode.HUKS_MODE_GCM
225e41f4b71Sopenharmony_ci    },
226e41f4b71Sopenharmony_ci    {
227e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_NONCE,
228e41f4b71Sopenharmony_ci      value: stringToUint8Array(NONCE)
229e41f4b71Sopenharmony_ci    },
230e41f4b71Sopenharmony_ci    {
231e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ASSOCIATED_DATA,
232e41f4b71Sopenharmony_ci      value: stringToUint8Array(AAD)
233e41f4b71Sopenharmony_ci    }
234e41f4b71Sopenharmony_ci  ),
235e41f4b71Sopenharmony_ci}
236e41f4b71Sopenharmony_cilet importWrappedAes192Params: huks.HuksOptions = {
237e41f4b71Sopenharmony_ci  properties: new Array<huks.HuksParam>(
238e41f4b71Sopenharmony_ci    {
239e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
240e41f4b71Sopenharmony_ci      value: huks.HuksKeyAlg.HUKS_ALG_AES
241e41f4b71Sopenharmony_ci    },
242e41f4b71Sopenharmony_ci    {
243e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PURPOSE,
244e41f4b71Sopenharmony_ci      value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
245e41f4b71Sopenharmony_ci      huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
246e41f4b71Sopenharmony_ci    },
247e41f4b71Sopenharmony_ci    {
248e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
249e41f4b71Sopenharmony_ci      value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_192
250e41f4b71Sopenharmony_ci    },
251e41f4b71Sopenharmony_ci    {
252e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_PADDING,
253e41f4b71Sopenharmony_ci      value: huks.HuksKeyPadding.HUKS_PADDING_NONE
254e41f4b71Sopenharmony_ci    },
255e41f4b71Sopenharmony_ci    {
256e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
257e41f4b71Sopenharmony_ci      value: huks.HuksCipherMode.HUKS_MODE_CBC
258e41f4b71Sopenharmony_ci    },
259e41f4b71Sopenharmony_ci    {
260e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_DIGEST,
261e41f4b71Sopenharmony_ci      value: huks.HuksKeyDigest.HUKS_DIGEST_NONE
262e41f4b71Sopenharmony_ci    },
263e41f4b71Sopenharmony_ci    {
264e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_UNWRAP_ALGORITHM_SUITE,
265e41f4b71Sopenharmony_ci      value: huks.HuksUnwrapSuite.HUKS_UNWRAP_SUITE_ECDH_AES_256_GCM_NOPADDING
266e41f4b71Sopenharmony_ci    },
267e41f4b71Sopenharmony_ci    {
268e41f4b71Sopenharmony_ci      tag: huks.HuksTag.HUKS_TAG_IV,
269e41f4b71Sopenharmony_ci      value: stringToUint8Array(IV)
270e41f4b71Sopenharmony_ci    }
271e41f4b71Sopenharmony_ci  )
272e41f4b71Sopenharmony_ci}
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ciasync function publicGenerateItemFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
275e41f4b71Sopenharmony_ci  console.info(`enter promise generateKeyItem`);
276e41f4b71Sopenharmony_ci  try {
277e41f4b71Sopenharmony_ci    await huks.generateKeyItem(keyAlias, huksOptions)
278e41f4b71Sopenharmony_ci      .then(data => {
279e41f4b71Sopenharmony_ci        console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`);
280e41f4b71Sopenharmony_ci      })
281e41f4b71Sopenharmony_ci      .catch((err: Error) => {
282e41f4b71Sopenharmony_ci        console.error(`promise: generateKeyItem failed, ${JSON.stringify(err)}`);
283e41f4b71Sopenharmony_ci      })
284e41f4b71Sopenharmony_ci  } catch (err) {
285e41f4b71Sopenharmony_ci    console.error(`promise: generateKeyItem invalid, ${JSON.stringify(err)}`);
286e41f4b71Sopenharmony_ci  }
287e41f4b71Sopenharmony_ci}
288e41f4b71Sopenharmony_ci
289e41f4b71Sopenharmony_ciasync function publicImportKeyItemFunc(keyAlias: string, HuksOptions: huks.HuksOptions) {
290e41f4b71Sopenharmony_ci  console.info(`enter promise importKeyItem`);
291e41f4b71Sopenharmony_ci  try {
292e41f4b71Sopenharmony_ci    await huks.importKeyItem(keyAlias, HuksOptions)
293e41f4b71Sopenharmony_ci      .then(data => {
294e41f4b71Sopenharmony_ci        console.info(`promise: importKeyItem success, data = ${JSON.stringify(data)}`);
295e41f4b71Sopenharmony_ci      }).catch((err: Error) => {
296e41f4b71Sopenharmony_ci        console.error(`promise: importKeyItem failed, ${JSON.stringify(err)}`);
297e41f4b71Sopenharmony_ci      })
298e41f4b71Sopenharmony_ci  } catch (err) {
299e41f4b71Sopenharmony_ci    console.error(`promise: importKeyItem input arg invalid, ${JSON.stringify(err)}`);
300e41f4b71Sopenharmony_ci  }
301e41f4b71Sopenharmony_ci}
302e41f4b71Sopenharmony_ci
303e41f4b71Sopenharmony_ciasync function publicDeleteKeyItemFunc(KeyAlias: string, HuksOptions: huks.HuksOptions) {
304e41f4b71Sopenharmony_ci  console.info(`enter promise deleteKeyItem`);
305e41f4b71Sopenharmony_ci  try {
306e41f4b71Sopenharmony_ci    await huks.deleteKeyItem(KeyAlias, HuksOptions)
307e41f4b71Sopenharmony_ci      .then(data => {
308e41f4b71Sopenharmony_ci        console.info(`promise: deleteKeyItem key success, data = ${JSON.stringify(data)}`);
309e41f4b71Sopenharmony_ci      })
310e41f4b71Sopenharmony_ci      .catch((err: Error) => {
311e41f4b71Sopenharmony_ci        console.error(`promise: deleteKeyItem failed, ${JSON.stringify(err)}`);
312e41f4b71Sopenharmony_ci      })
313e41f4b71Sopenharmony_ci  } catch (err) {
314e41f4b71Sopenharmony_ci    console.error(`promise: deleteKeyItem input arg invalid, ${JSON.stringify(err)}`);
315e41f4b71Sopenharmony_ci  }
316e41f4b71Sopenharmony_ci}
317e41f4b71Sopenharmony_ci
318e41f4b71Sopenharmony_cifunction importWrappedKeyItem(keyAlias: string, wrappingKeyAlias: string, huksOptions: huks.HuksOptions) {
319e41f4b71Sopenharmony_ci  return new Promise<void>((resolve, reject) => {
320e41f4b71Sopenharmony_ci    try {
321e41f4b71Sopenharmony_ci      huks.importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions, (error, data) => {
322e41f4b71Sopenharmony_ci        if (error) {
323e41f4b71Sopenharmony_ci          reject(error);
324e41f4b71Sopenharmony_ci        } else {
325e41f4b71Sopenharmony_ci          resolve(data);
326e41f4b71Sopenharmony_ci        }
327e41f4b71Sopenharmony_ci      });
328e41f4b71Sopenharmony_ci    } catch (error) {
329e41f4b71Sopenharmony_ci    }
330e41f4b71Sopenharmony_ci  });
331e41f4b71Sopenharmony_ci}
332e41f4b71Sopenharmony_ci
333e41f4b71Sopenharmony_ciasync function publicImportWrappedKeyFunc(keyAlias: string, wrappingKeyAlias: string, huksOptions: huks.HuksOptions) {
334e41f4b71Sopenharmony_ci  console.info(`enter promise importWrappedKeyItem`);
335e41f4b71Sopenharmony_ci  for (let i = 0; i < huksOptions.inData!.length; i++) {
336e41f4b71Sopenharmony_ci    console.error(`${i}: ${huksOptions.inData![i]}`);
337e41f4b71Sopenharmony_ci  }
338e41f4b71Sopenharmony_ci  try {
339e41f4b71Sopenharmony_ci    await importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions)
340e41f4b71Sopenharmony_ci      .then((data) => {
341e41f4b71Sopenharmony_ci        console.info(`promise: importWrappedKeyItem success, data = ${JSON.stringify(data)}`);
342e41f4b71Sopenharmony_ci      })
343e41f4b71Sopenharmony_ci      .catch((error: Error) => {
344e41f4b71Sopenharmony_ci        console.error(`promise: importWrappedKeyItem failed, ${JSON.stringify(error)}`);
345e41f4b71Sopenharmony_ci      });
346e41f4b71Sopenharmony_ci  } catch (error) {
347e41f4b71Sopenharmony_ci    console.error(`promise: importWrappedKeyItem input arg invalid, ${JSON.stringify(error)}`);
348e41f4b71Sopenharmony_ci  }
349e41f4b71Sopenharmony_ci}
350e41f4b71Sopenharmony_ci
351e41f4b71Sopenharmony_ciasync function publicImportWrappedKeyPromise(keyAlias: string, wrappingKeyAlias: string,
352e41f4b71Sopenharmony_ci  huksOptions: huks.HuksOptions) {
353e41f4b71Sopenharmony_ci  console.info(`enter promise importWrappedKeyItem`);
354e41f4b71Sopenharmony_ci  try {
355e41f4b71Sopenharmony_ci    await huks.importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions)
356e41f4b71Sopenharmony_ci      .then((data) => {
357e41f4b71Sopenharmony_ci        console.info(`promise: importWrappedKeyItem success, data = ${JSON.stringify(data)}`);
358e41f4b71Sopenharmony_ci      })
359e41f4b71Sopenharmony_ci      .catch((error: Error) => {
360e41f4b71Sopenharmony_ci        console.error(`promise: importWrappedKeyItem failed, ${JSON.stringify(error)}`);
361e41f4b71Sopenharmony_ci      });
362e41f4b71Sopenharmony_ci  } catch (error) {
363e41f4b71Sopenharmony_ci    console.error(`promise: importWrappedKeyItem input arg invalid, ${JSON.stringify(error)}`);
364e41f4b71Sopenharmony_ci  }
365e41f4b71Sopenharmony_ci}
366e41f4b71Sopenharmony_ci
367e41f4b71Sopenharmony_ciasync function publicInitFunc(srcKeyAlias: string, HuksOptions: huks.HuksOptions) {
368e41f4b71Sopenharmony_ci  let handle: number = 0;
369e41f4b71Sopenharmony_ci  console.info(`enter promise doInit`);
370e41f4b71Sopenharmony_ci  try {
371e41f4b71Sopenharmony_ci    await huks.initSession(srcKeyAlias, HuksOptions)
372e41f4b71Sopenharmony_ci      .then((data) => {
373e41f4b71Sopenharmony_ci        console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
374e41f4b71Sopenharmony_ci        handle = data.handle;
375e41f4b71Sopenharmony_ci      })
376e41f4b71Sopenharmony_ci      .catch((error: Error) => {
377e41f4b71Sopenharmony_ci        console.error(`promise: doInit key failed, ${JSON.stringify(error)}`);
378e41f4b71Sopenharmony_ci      });
379e41f4b71Sopenharmony_ci  } catch (error) {
380e41f4b71Sopenharmony_ci    console.error(`promise: doInit input arg invalid, ${JSON.stringify(error)}`);
381e41f4b71Sopenharmony_ci  }
382e41f4b71Sopenharmony_ci  return handle;
383e41f4b71Sopenharmony_ci}
384e41f4b71Sopenharmony_ci
385e41f4b71Sopenharmony_ciasync function publicUpdateSessionFunction(handle: number, HuksOptions: huks.HuksOptions) {
386e41f4b71Sopenharmony_ci  const maxUpdateSize = 64;
387e41f4b71Sopenharmony_ci  const inData = HuksOptions.inData!;
388e41f4b71Sopenharmony_ci  const lastInDataPosition = inData.length - 1;
389e41f4b71Sopenharmony_ci  let inDataSegSize = maxUpdateSize;
390e41f4b71Sopenharmony_ci  let inDataSegPosition = 0;
391e41f4b71Sopenharmony_ci  let isFinished = false;
392e41f4b71Sopenharmony_ci  let outData: number[] = [];
393e41f4b71Sopenharmony_ci
394e41f4b71Sopenharmony_ci  while (inDataSegPosition <= lastInDataPosition) {
395e41f4b71Sopenharmony_ci    if (inDataSegPosition + maxUpdateSize > lastInDataPosition) {
396e41f4b71Sopenharmony_ci      isFinished = true;
397e41f4b71Sopenharmony_ci      inDataSegSize = lastInDataPosition - inDataSegPosition + 1;
398e41f4b71Sopenharmony_ci      console.info(`enter promise doUpdate`);
399e41f4b71Sopenharmony_ci      break;
400e41f4b71Sopenharmony_ci    }
401e41f4b71Sopenharmony_ci    HuksOptions.inData = new Uint8Array(
402e41f4b71Sopenharmony_ci      Array.from(inData).slice(inDataSegPosition, inDataSegPosition + inDataSegSize)
403e41f4b71Sopenharmony_ci    );
404e41f4b71Sopenharmony_ci    console.info(`enter promise doUpdate`);
405e41f4b71Sopenharmony_ci    try {
406e41f4b71Sopenharmony_ci      await huks.updateSession(handle, HuksOptions)
407e41f4b71Sopenharmony_ci        .then((data) => {
408e41f4b71Sopenharmony_ci          console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`);
409e41f4b71Sopenharmony_ci          outData = outData.concat(Array.from(data.outData!));
410e41f4b71Sopenharmony_ci        })
411e41f4b71Sopenharmony_ci        .catch((error: Error) => {
412e41f4b71Sopenharmony_ci          console.error(`promise: doUpdate failed, ${JSON.stringify(error)}`);
413e41f4b71Sopenharmony_ci        });
414e41f4b71Sopenharmony_ci    } catch (error) {
415e41f4b71Sopenharmony_ci      console.error(`promise: doUpdate input arg invalid, ${JSON.stringify(error)}`);
416e41f4b71Sopenharmony_ci    }
417e41f4b71Sopenharmony_ci    if ((!isFinished) && (inDataSegPosition + maxUpdateSize > lastInDataPosition)) {
418e41f4b71Sopenharmony_ci      console.error(`update size invalid isFinished = ${isFinished}`);
419e41f4b71Sopenharmony_ci      console.error(`inDataSegPosition = ${inDataSegPosition}`);
420e41f4b71Sopenharmony_ci      console.error(`lastInDataPosition = ${lastInDataPosition}`);
421e41f4b71Sopenharmony_ci      return;
422e41f4b71Sopenharmony_ci    }
423e41f4b71Sopenharmony_ci    inDataSegPosition += maxUpdateSize;
424e41f4b71Sopenharmony_ci  }
425e41f4b71Sopenharmony_ci  return outData;
426e41f4b71Sopenharmony_ci}
427e41f4b71Sopenharmony_ci
428e41f4b71Sopenharmony_ciasync function publicFinishSession(handle: number, HuksOptions: huks.HuksOptions, inData: number[]) {
429e41f4b71Sopenharmony_ci  let outData: number[] = [];
430e41f4b71Sopenharmony_ci  console.info(`enter promise doFinish`);
431e41f4b71Sopenharmony_ci  try {
432e41f4b71Sopenharmony_ci    await huks.finishSession(handle, HuksOptions)
433e41f4b71Sopenharmony_ci      .then((data) => {
434e41f4b71Sopenharmony_ci        console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
435e41f4b71Sopenharmony_ci        outData = inData.concat(Array.from(data.outData!));
436e41f4b71Sopenharmony_ci      })
437e41f4b71Sopenharmony_ci      .catch((error: Error) => {
438e41f4b71Sopenharmony_ci        console.error(`promise: doFinish key failed, ${JSON.stringify(error)}`);
439e41f4b71Sopenharmony_ci      });
440e41f4b71Sopenharmony_ci  } catch (error) {
441e41f4b71Sopenharmony_ci    console.error(`promise: doFinish input arg invalid, ${JSON.stringify(error)}`);
442e41f4b71Sopenharmony_ci  }
443e41f4b71Sopenharmony_ci  return new Uint8Array(outData);
444e41f4b71Sopenharmony_ci}
445e41f4b71Sopenharmony_ci
446e41f4b71Sopenharmony_ciasync function cipherFunction(keyAlias: string, HuksOptions: huks.HuksOptions) {
447e41f4b71Sopenharmony_ci  let handle = await publicInitFunc(keyAlias, HuksOptions);
448e41f4b71Sopenharmony_ci  let tmpData = await publicUpdateSessionFunction(handle, HuksOptions);
449e41f4b71Sopenharmony_ci  let outData = await publicFinishSession(handle, HuksOptions, tmpData!);
450e41f4b71Sopenharmony_ci  return outData;
451e41f4b71Sopenharmony_ci}
452e41f4b71Sopenharmony_ci
453e41f4b71Sopenharmony_ciasync function agreeFunction(keyAlias: string, HuksOptions: huks.HuksOptions, huksPublicKey: Uint8Array) {
454e41f4b71Sopenharmony_ci  let handle = await publicInitFunc(keyAlias, HuksOptions);
455e41f4b71Sopenharmony_ci  let outSharedKey: Uint8Array = new Uint8Array;
456e41f4b71Sopenharmony_ci  HuksOptions.inData = huksPublicKey;
457e41f4b71Sopenharmony_ci  console.info(`enter promise doUpdate`);
458e41f4b71Sopenharmony_ci  try {
459e41f4b71Sopenharmony_ci    await huks.updateSession(handle, HuksOptions)
460e41f4b71Sopenharmony_ci      .then((data) => {
461e41f4b71Sopenharmony_ci        console.error(`promise: doUpdate success, data = ${JSON.stringify(data)}`);
462e41f4b71Sopenharmony_ci      })
463e41f4b71Sopenharmony_ci      .catch((error: Error) => {
464e41f4b71Sopenharmony_ci        console.error(`promise: doUpdate failed, ${JSON.stringify(error)}`);
465e41f4b71Sopenharmony_ci      });
466e41f4b71Sopenharmony_ci  } catch (error) {
467e41f4b71Sopenharmony_ci    console.error(`promise: doUpdate input arg invalid, ${JSON.stringify(error)}`);
468e41f4b71Sopenharmony_ci  }
469e41f4b71Sopenharmony_ci  console.info(`enter promise doInit`);
470e41f4b71Sopenharmony_ci  try {
471e41f4b71Sopenharmony_ci    await huks.finishSession(handle, HuksOptions)
472e41f4b71Sopenharmony_ci      .then((data) => {
473e41f4b71Sopenharmony_ci        console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
474e41f4b71Sopenharmony_ci        outSharedKey = data.outData as Uint8Array;
475e41f4b71Sopenharmony_ci      })
476e41f4b71Sopenharmony_ci      .catch((error: Error) => {
477e41f4b71Sopenharmony_ci        console.error(`promise: doInit key failed, ${JSON.stringify(error)}`);
478e41f4b71Sopenharmony_ci      });
479e41f4b71Sopenharmony_ci  } catch (error) {
480e41f4b71Sopenharmony_ci    console.error(`promise: doInit input arg invalid, ${JSON.stringify(error)}`);
481e41f4b71Sopenharmony_ci  }
482e41f4b71Sopenharmony_ci  return outSharedKey;
483e41f4b71Sopenharmony_ci}
484e41f4b71Sopenharmony_ci
485e41f4b71Sopenharmony_ciasync function ImportKekAndAgreeSharedSecret(callerKekAlias: string, importKekParams: huks.HuksOptions,
486e41f4b71Sopenharmony_ci  callerKeyAlias: string, huksPublicKey: Uint8Array, agreeParams: huks.HuksOptions) {
487e41f4b71Sopenharmony_ci  await publicImportKeyItemFunc(callerKekAlias, importKekParams);
488e41f4b71Sopenharmony_ci  outSharedKey = await agreeFunction(callerKeyAlias, agreeParams, huksPublicKey);
489e41f4b71Sopenharmony_ci  importParamsAgreeKey.inData = outSharedKey;
490e41f4b71Sopenharmony_ci  await publicImportKeyItemFunc(callerAgreeKeyAliasAes256, importParamsAgreeKey);
491e41f4b71Sopenharmony_ci}
492e41f4b71Sopenharmony_ci
493e41f4b71Sopenharmony_ciasync function generateAndExportPublicKey(keyAlias: string, HuksOptions: huks.HuksOptions, caller: Boolean) {
494e41f4b71Sopenharmony_ci  await publicGenerateItemFunc(keyAlias, HuksOptions);
495e41f4b71Sopenharmony_ci  try {
496e41f4b71Sopenharmony_ci    await huks.exportKeyItem(keyAlias, HuksOptions)
497e41f4b71Sopenharmony_ci      .then((data) => {
498e41f4b71Sopenharmony_ci        console.info(`promise: exportKeyItem success, data = ${JSON.stringify(data)}`);
499e41f4b71Sopenharmony_ci        if (caller) {
500e41f4b71Sopenharmony_ci          callerSelfPublicKey = data.outData as Uint8Array;
501e41f4b71Sopenharmony_ci        } else {
502e41f4b71Sopenharmony_ci          huksPubKey = data.outData as Uint8Array;
503e41f4b71Sopenharmony_ci        }
504e41f4b71Sopenharmony_ci      })
505e41f4b71Sopenharmony_ci      .catch((error: Error) => {
506e41f4b71Sopenharmony_ci        console.error(`promise: exportKeyItem failed, ${JSON.stringify(error)}`);
507e41f4b71Sopenharmony_ci      });
508e41f4b71Sopenharmony_ci  } catch (error) {
509e41f4b71Sopenharmony_ci    console.error(`promise: generate pubKey failed, ${JSON.stringify(error)}`);
510e41f4b71Sopenharmony_ci  }
511e41f4b71Sopenharmony_ci}
512e41f4b71Sopenharmony_ci
513e41f4b71Sopenharmony_ciasync function EncryptImportedPlainKeyAndKek(keyAlias: string) {
514e41f4b71Sopenharmony_ci  encryptKeyCommonParams.inData = stringToUint8Array(keyAlias)
515e41f4b71Sopenharmony_ci  let plainKeyEncData = await cipherFunction(callerKekAliasAes256, encryptKeyCommonParams);
516e41f4b71Sopenharmony_ci  outKekEncTag = subUint8ArrayOf(plainKeyEncData, plainKeyEncData.length - TAG_SIZE, plainKeyEncData.length)
517e41f4b71Sopenharmony_ci  outPlainKeyEncData = subUint8ArrayOf(plainKeyEncData, 0, plainKeyEncData.length - TAG_SIZE)
518e41f4b71Sopenharmony_ci  encryptKeyCommonParams.inData = stringToUint8Array(callerAes256Kek)
519e41f4b71Sopenharmony_ci  let kekEncData = await cipherFunction(callerAgreeKeyAliasAes256, encryptKeyCommonParams)
520e41f4b71Sopenharmony_ci  outAgreeKeyEncTag = subUint8ArrayOf(kekEncData, kekEncData.length - TAG_SIZE, kekEncData.length)
521e41f4b71Sopenharmony_ci  outKekEncData = subUint8ArrayOf(kekEncData, 0, kekEncData.length - TAG_SIZE)
522e41f4b71Sopenharmony_ci}
523e41f4b71Sopenharmony_ci
524e41f4b71Sopenharmony_ciasync function BuildWrappedDataAndImportWrappedKey(plainKey: string) {
525e41f4b71Sopenharmony_ci  let plainKeySizeBuff = new Uint8Array(4);
526e41f4b71Sopenharmony_ci  assignLength(plainKey.length, plainKeySizeBuff, 0);
527e41f4b71Sopenharmony_ci  let wrappedData = new Uint8Array(
528e41f4b71Sopenharmony_ci    FILED_LENGTH + huksPubKey.length +
529e41f4b71Sopenharmony_ci      FILED_LENGTH + AAD.length +
530e41f4b71Sopenharmony_ci      FILED_LENGTH + NONCE.length +
531e41f4b71Sopenharmony_ci      FILED_LENGTH + TAG_SIZE +
532e41f4b71Sopenharmony_ci      FILED_LENGTH + outKekEncData.length +
533e41f4b71Sopenharmony_ci      FILED_LENGTH + AAD.length +
534e41f4b71Sopenharmony_ci      FILED_LENGTH + NONCE.length +
535e41f4b71Sopenharmony_ci      FILED_LENGTH + TAG_SIZE +
536e41f4b71Sopenharmony_ci      FILED_LENGTH + plainKeySizeBuff.length +
537e41f4b71Sopenharmony_ci      FILED_LENGTH + outPlainKeyEncData.length
538e41f4b71Sopenharmony_ci  );
539e41f4b71Sopenharmony_ci  let index = 0;
540e41f4b71Sopenharmony_ci  let AADUint8Array = stringToUint8Array(AAD);
541e41f4b71Sopenharmony_ci  let NonceArray = stringToUint8Array(NONCE);
542e41f4b71Sopenharmony_ci  index += assignLength(callerSelfPublicKey.length, wrappedData, index); // 4
543e41f4b71Sopenharmony_ci  index += assignData(callerSelfPublicKey, wrappedData, index); // 91
544e41f4b71Sopenharmony_ci  index += assignLength(AADUint8Array.length, wrappedData, index); // 4
545e41f4b71Sopenharmony_ci  index += assignData(AADUint8Array, wrappedData, index); // 16
546e41f4b71Sopenharmony_ci  index += assignLength(NonceArray.length, wrappedData, index); // 4
547e41f4b71Sopenharmony_ci  index += assignData(NonceArray, wrappedData, index); // 12
548e41f4b71Sopenharmony_ci  index += assignLength(outAgreeKeyEncTag.length, wrappedData, index); // 4
549e41f4b71Sopenharmony_ci  index += assignData(outAgreeKeyEncTag, wrappedData, index); // 16
550e41f4b71Sopenharmony_ci  index += assignLength(outKekEncData.length, wrappedData, index); // 4
551e41f4b71Sopenharmony_ci  index += assignData(outKekEncData, wrappedData, index); // 32
552e41f4b71Sopenharmony_ci  index += assignLength(AADUint8Array.length, wrappedData, index); // 4
553e41f4b71Sopenharmony_ci  index += assignData(AADUint8Array, wrappedData, index); // 16
554e41f4b71Sopenharmony_ci  index += assignLength(NonceArray.length, wrappedData, index); // 4
555e41f4b71Sopenharmony_ci  index += assignData(NonceArray, wrappedData, index); // 12
556e41f4b71Sopenharmony_ci  index += assignLength(outKekEncTag.length, wrappedData, index); // 4
557e41f4b71Sopenharmony_ci  index += assignData(outKekEncTag, wrappedData, index); // 16
558e41f4b71Sopenharmony_ci  index += assignLength(plainKeySizeBuff.length, wrappedData, index); // 4
559e41f4b71Sopenharmony_ci  index += assignData(plainKeySizeBuff, wrappedData, index); // 4
560e41f4b71Sopenharmony_ci  index += assignLength(outPlainKeyEncData.length, wrappedData, index); // 4
561e41f4b71Sopenharmony_ci  index += assignData(outPlainKeyEncData, wrappedData, index); // 24
562e41f4b71Sopenharmony_ci  return wrappedData;
563e41f4b71Sopenharmony_ci}
564e41f4b71Sopenharmony_ci
565e41f4b71Sopenharmony_ci/* Simulate the encrypted key import scenario. Import a key from device A (remote device) to device B (local device). */
566e41f4b71Sopenharmony_ciasync function ImportWrappedKey() {
567e41f4b71Sopenharmony_ci  /**
568e41f4b71Sopenharmony_ci   * 1. If the key to be imported from device A is an asymmetric key pair, convert it into the HUKS key material format **To_Import_Key**. Skip over this step if the key is a symmetric key.
569e41f4b71Sopenharmony_ci   * This example uses a 256-bit AES key (symmetric key) as an example.
570e41f4b71Sopenharmony_ci   */
571e41f4b71Sopenharmony_ci
572e41f4b71Sopenharmony_ci  /* 2. Generate an asymmetric key pair Wrapping_Key (public key Wrapping_Pk and private key Wrapping_Sk) with the purpose of HUKS_KEY_PURPOSE_UNWRAP for device B, export the public key Wrapping_Pk of Wrapping_Key, and save it to huksPubKey. */
573e41f4b71Sopenharmony_ci  const srcKeyAliasWrap = 'HUKS_Basic_Capability_Import_0200';
574e41f4b71Sopenharmony_ci  await generateAndExportPublicKey(srcKeyAliasWrap, genWrappingKeyParams, false);
575e41f4b71Sopenharmony_ci
576e41f4b71Sopenharmony_ci  /* 3. Use the same algorithm to generate an asymmetric key pair Caller_Key (public key Caller_Pk and private key Caller_Sk) with the purpose of HUKS_KEY_PURPOSE_UNWRAP for device A, export the public key Caller_Pk of Caller_Key, save it to callerSelfPublicKey. */
577e41f4b71Sopenharmony_ci  await generateAndExportPublicKey(callerKeyAlias, genCallerEcdhParams, true);
578e41f4b71Sopenharmony_ci
579e41f4b71Sopenharmony_ci  /**
580e41f4b71Sopenharmony_ci   4. Generate a symmetric key Caller_Kek for device A. This key is used to encrypt To_Import_Key.
581e41f4b71Sopenharmony_ci   * 5. Perform key agreement with the private key Caller_Sk in Caller_Key of device A and the public key Wrapping_Pk in Wrapping_Key of device B to yield a Shared_Key.
582e41f4b71Sopenharmony_ci   */
583e41f4b71Sopenharmony_ci  await ImportKekAndAgreeSharedSecret(callerKekAliasAes256, importParamsCallerKek, callerKeyAlias, huksPubKey,
584e41f4b71Sopenharmony_ci    callerAgreeParams);
585e41f4b71Sopenharmony_ci
586e41f4b71Sopenharmony_ci  /**
587e41f4b71Sopenharmony_ci   * 6. Use Caller_Kek to encrypt To_Import_Key of device A and generate To_Import_Key_Enc.
588e41f4b71Sopenharmony_ci   * 7. Use Shared_Key to encrypt Caller_Kek of device A and generate Caller_Kek_Enc.
589e41f4b71Sopenharmony_ci   */
590e41f4b71Sopenharmony_ci  await EncryptImportedPlainKeyAndKek(importedAes192PlainKey);
591e41f4b71Sopenharmony_ci
592e41f4b71Sopenharmony_ci  /* 8. Encapsulate the key material Caller_Pk, To_Import_Key_Enc, and Caller_Kek_Enc of device A, and sends it to device B. In this example, Caller_Pk is placed in callerSelfPublicKey, To_Import_Key_Enc in PlainKeyEncData, and Caller_Kek_Enc in KekEncData. */
593e41f4b71Sopenharmony_ci  let wrappedData = await BuildWrappedDataAndImportWrappedKey(importedAes192PlainKey);
594e41f4b71Sopenharmony_ci  importWrappedAes192Params.inData = wrappedData;
595e41f4b71Sopenharmony_ci
596e41f4b71Sopenharmony_ci  /* 9. Import the encapsulated key material to device B. */
597e41f4b71Sopenharmony_ci  await publicImportWrappedKeyFunc(importedKeyAliasAes192, srcKeyAliasWrap, importWrappedAes192Params);
598e41f4b71Sopenharmony_ci
599e41f4b71Sopenharmony_ci  /* 10. Delete the intermediate keys (keys used for encrypting the key to import) from devices A and B. */
600e41f4b71Sopenharmony_ci  await publicDeleteKeyItemFunc(srcKeyAliasWrap, genWrappingKeyParams);
601e41f4b71Sopenharmony_ci  await publicDeleteKeyItemFunc(callerKeyAlias, genCallerEcdhParams);
602e41f4b71Sopenharmony_ci  await publicDeleteKeyItemFunc(importedKeyAliasAes192, importWrappedAes192Params);
603e41f4b71Sopenharmony_ci  await publicDeleteKeyItemFunc(callerKekAliasAes256, callerAgreeParams);
604e41f4b71Sopenharmony_ci}
605e41f4b71Sopenharmony_ci
606e41f4b71Sopenharmony_ci```
607e41f4b71Sopenharmony_ci
608e41f4b71Sopenharmony_ci
609e41f4b71Sopenharmony_ci## Verification
610e41f4b71Sopenharmony_ci
611e41f4b71Sopenharmony_ciUse [huks.isKeyItemExist](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksiskeyitemexist9) to check whether the key exists. If the key exists, the key is successfully imported.
612e41f4b71Sopenharmony_ci
613e41f4b71Sopenharmony_ci```ts
614e41f4b71Sopenharmony_ciimport { huks } from '@kit.UniversalKeystoreKit';
615e41f4b71Sopenharmony_ci
616e41f4b71Sopenharmony_ci/*
617e41f4b71Sopenharmony_ci * Set the key alias and encapsulate the key property set.
618e41f4b71Sopenharmony_ci */
619e41f4b71Sopenharmony_cilet keyAlias = 'test_import_key_ecdh_aes192';
620e41f4b71Sopenharmony_cilet isKeyExist: Boolean;
621e41f4b71Sopenharmony_cilet keyProperties: Array<huks.HuksParam> = [{
622e41f4b71Sopenharmony_ci  tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
623e41f4b71Sopenharmony_ci  value: huks.HuksKeyAlg.HUKS_ALG_AES,
624e41f4b71Sopenharmony_ci}];
625e41f4b71Sopenharmony_cilet huksOptions: huks.HuksOptions = {
626e41f4b71Sopenharmony_ci  properties: keyProperties, // It cannot be empty.
627e41f4b71Sopenharmony_ci  inData: new Uint8Array(new Array()) // It cannot be empty.
628e41f4b71Sopenharmony_ci}
629e41f4b71Sopenharmony_citry {
630e41f4b71Sopenharmony_ci  huks.isKeyItemExist(keyAlias, huksOptions, (error, data) => {
631e41f4b71Sopenharmony_ci    if (error) {
632e41f4b71Sopenharmony_ci      console.error(`callback: isKeyItemExist failed, ${JSON.stringify(error)}`);
633e41f4b71Sopenharmony_ci    } else {
634e41f4b71Sopenharmony_ci      if (data !== null && data.valueOf() !== null) {
635e41f4b71Sopenharmony_ci        isKeyExist = data.valueOf();
636e41f4b71Sopenharmony_ci        console.info(`callback: isKeyItemExist success, isKeyExist = ${isKeyExist}`);
637e41f4b71Sopenharmony_ci      }
638e41f4b71Sopenharmony_ci    }
639e41f4b71Sopenharmony_ci  });
640e41f4b71Sopenharmony_ci} catch (error) {
641e41f4b71Sopenharmony_ci  console.error(`callback: isKeyItemExist input arg invalid, ${JSON.stringify(error)}`);
642e41f4b71Sopenharmony_ci}
643e41f4b71Sopenharmony_ci```
644