1e41f4b71Sopenharmony_ci# Refined Key Access Control Development
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciAs an extension of the access control based on user identity authentication, the refined key access control provides fine-grained access control capabilities via secondary identity authentication based on biometric features and lock screen passwords. You can set whether identity authentication is required for a key in one or more scenarios such as encryption, decryption, signing, signature verification, key agreement, and key derivation.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciFor example, a service needs to use a HUKS key to encrypt the account password information. In this scenario, identity authentication is not required in encryption but required in decryption. To achieve this purpose, you can use the refined access control feature provided by HUKS.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciTo implement this feature, you only need to set **HuksTag** to **HUKS_TAG_KEY_AUTH_PURPOSE**.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci> **NOTE**<br>
10e41f4b71Sopenharmony_ci> For symmetric encryption and decryption, only the AES/CBC, AES/GCM, and SM4/CBC modes support fine-grained access control.
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci## How to Develop
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci1. Generate a key, set HuksUserAuthType to fingerprint authentication, and set other parameters including **HUKS_TAG_KEY_AUTH_PURPOSE**.
15e41f4b71Sopenharmony_ci   
16e41f4b71Sopenharmony_ci   ```ts
17e41f4b71Sopenharmony_ci   import { huks } from "@kit.UniversalKeystoreKit";
18e41f4b71Sopenharmony_ci   /*
19e41f4b71Sopenharmony_ci    * Set the key alias and encapsulate the key property set.
20e41f4b71Sopenharmony_ci    */
21e41f4b71Sopenharmony_ci   let keyAlias = 'test_sm4_key_alias';
22e41f4b71Sopenharmony_ci   class throwObject {
23e41f4b71Sopenharmony_ci       isThrow: boolean = false;
24e41f4b71Sopenharmony_ci   }
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci   let properties: Array<huks.HuksParam> = [
27e41f4b71Sopenharmony_ci       {
28e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
29e41f4b71Sopenharmony_ci           value: huks.HuksKeyAlg.HUKS_ALG_SM4,
30e41f4b71Sopenharmony_ci       },
31e41f4b71Sopenharmony_ci       {
32e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_PURPOSE,
33e41f4b71Sopenharmony_ci           value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
34e41f4b71Sopenharmony_ci       },
35e41f4b71Sopenharmony_ci       {
36e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
37e41f4b71Sopenharmony_ci           value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
38e41f4b71Sopenharmony_ci       },
39e41f4b71Sopenharmony_ci       {
40e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
41e41f4b71Sopenharmony_ci           value: huks.HuksCipherMode.HUKS_MODE_CBC,
42e41f4b71Sopenharmony_ci       },
43e41f4b71Sopenharmony_ci       {
44e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_PADDING,
45e41f4b71Sopenharmony_ci           value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
46e41f4b71Sopenharmony_ci       },
47e41f4b71Sopenharmony_ci       {
48e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE,
49e41f4b71Sopenharmony_ci           value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT
50e41f4b71Sopenharmony_ci       },
51e41f4b71Sopenharmony_ci       {
52e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE,
53e41f4b71Sopenharmony_ci           value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL
54e41f4b71Sopenharmony_ci       },
55e41f4b71Sopenharmony_ci       {
56e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE,
57e41f4b71Sopenharmony_ci           value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL
58e41f4b71Sopenharmony_ci       },
59e41f4b71Sopenharmony_ci       {
60e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_PURPOSE,
61e41f4b71Sopenharmony_ci           value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
62e41f4b71Sopenharmony_ci       }
63e41f4b71Sopenharmony_ci   ];
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci   let huksOptions: huks.HuksOptions = {
66e41f4b71Sopenharmony_ci       properties: properties,
67e41f4b71Sopenharmony_ci       inData: new Uint8Array(new Array())
68e41f4b71Sopenharmony_ci   }
69e41f4b71Sopenharmony_ci   /*
70e41f4b71Sopenharmony_ci    * Generate a key.
71e41f4b71Sopenharmony_ci    */
72e41f4b71Sopenharmony_ci   async function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
73e41f4b71Sopenharmony_ci       return new Promise<void>((resolve, reject) => {
74e41f4b71Sopenharmony_ci           try {
75e41f4b71Sopenharmony_ci               huks.generateKeyItem(keyAlias, huksOptions, (error, data) => {
76e41f4b71Sopenharmony_ci                   if (error) {
77e41f4b71Sopenharmony_ci                       reject(error);
78e41f4b71Sopenharmony_ci                   } else {
79e41f4b71Sopenharmony_ci                       resolve(data);
80e41f4b71Sopenharmony_ci                   }
81e41f4b71Sopenharmony_ci               });
82e41f4b71Sopenharmony_ci           } catch (error) {
83e41f4b71Sopenharmony_ci               throwObject.isThrow = true;
84e41f4b71Sopenharmony_ci               throw(error as Error);
85e41f4b71Sopenharmony_ci           }
86e41f4b71Sopenharmony_ci       });
87e41f4b71Sopenharmony_ci   }
88e41f4b71Sopenharmony_ci   async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
89e41f4b71Sopenharmony_ci       console.info(`enter promise generateKeyItem`);
90e41f4b71Sopenharmony_ci       let throwObject: throwObject = {isThrow: false};
91e41f4b71Sopenharmony_ci       try {
92e41f4b71Sopenharmony_ci           await generateKeyItem(keyAlias, huksOptions, throwObject)
93e41f4b71Sopenharmony_ci           .then((data) => {
94e41f4b71Sopenharmony_ci               console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`);
95e41f4b71Sopenharmony_ci           })
96e41f4b71Sopenharmony_ci           .catch((error: Error) => {
97e41f4b71Sopenharmony_ci               if (throwObject.isThrow) {
98e41f4b71Sopenharmony_ci                   throw(error as Error);
99e41f4b71Sopenharmony_ci               } else {
100e41f4b71Sopenharmony_ci                   console.error(`promise: generateKeyItem failed` + JSON.stringify(error));
101e41f4b71Sopenharmony_ci               }
102e41f4b71Sopenharmony_ci           });
103e41f4b71Sopenharmony_ci       } catch (error) {
104e41f4b71Sopenharmony_ci           console.error(`promise: generateKeyItem input arg invalid` + JSON.stringify(error));
105e41f4b71Sopenharmony_ci       }
106e41f4b71Sopenharmony_ci   }
107e41f4b71Sopenharmony_ci   async function TestGenKeyForFingerprintAccessControl() {
108e41f4b71Sopenharmony_ci       await publicGenKeyFunc(keyAlias, huksOptions);
109e41f4b71Sopenharmony_ci   }
110e41f4b71Sopenharmony_ci   ```
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci2. Use the key. User identity authentication is not required when the key is used for encryption.
113e41f4b71Sopenharmony_ci   
114e41f4b71Sopenharmony_ci   ```ts
115e41f4b71Sopenharmony_ci   import { huks } from "@kit.UniversalKeystoreKit";
116e41f4b71Sopenharmony_ci   class HuksProperties {
117e41f4b71Sopenharmony_ci       tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM;
118e41f4b71Sopenharmony_ci       value: huks.HuksKeyAlg | huks.HuksKeySize | huks.HuksKeyPurpose | huks.HuksKeyPadding | huks.HuksCipherMode 
119e41f4b71Sopenharmony_ci           | Uint8Array = huks.HuksKeyAlg.HUKS_ALG_ECC;
120e41f4b71Sopenharmony_ci   }
121e41f4b71Sopenharmony_ci   /*
122e41f4b71Sopenharmony_ci    * Set the key alias and encapsulate the key property set.
123e41f4b71Sopenharmony_ci    */
124e41f4b71Sopenharmony_ci   let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; // Plaintext
125e41f4b71Sopenharmony_ci   let IV = '1234567890123456';
126e41f4b71Sopenharmony_ci   let handle = 0;
127e41f4b71Sopenharmony_ci   let cipherText: Uint8Array; // Ciphertext after encryption.
128e41f4b71Sopenharmony_ci   function StringToUint8Array(str: string) {
129e41f4b71Sopenharmony_ci       let arr: number[] = [];
130e41f4b71Sopenharmony_ci       for (let i = 0, j = str.length; i < j; ++i) {
131e41f4b71Sopenharmony_ci           arr.push(str.charCodeAt(i));
132e41f4b71Sopenharmony_ci       }
133e41f4b71Sopenharmony_ci       return new Uint8Array(arr);
134e41f4b71Sopenharmony_ci   }
135e41f4b71Sopenharmony_ci   /* Set the key generation parameter set and key encryption parameter set. */
136e41f4b71Sopenharmony_ci   let propertiesEncrypt: HuksProperties[] = [
137e41f4b71Sopenharmony_ci       {
138e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
139e41f4b71Sopenharmony_ci           value: huks.HuksKeyAlg.HUKS_ALG_SM4,
140e41f4b71Sopenharmony_ci       },
141e41f4b71Sopenharmony_ci       {
142e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_PURPOSE,
143e41f4b71Sopenharmony_ci           value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT,
144e41f4b71Sopenharmony_ci       },
145e41f4b71Sopenharmony_ci       {
146e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
147e41f4b71Sopenharmony_ci           value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
148e41f4b71Sopenharmony_ci       },
149e41f4b71Sopenharmony_ci       {
150e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_PADDING,
151e41f4b71Sopenharmony_ci           value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
152e41f4b71Sopenharmony_ci       },
153e41f4b71Sopenharmony_ci       {
154e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
155e41f4b71Sopenharmony_ci           value: huks.HuksCipherMode.HUKS_MODE_CBC,
156e41f4b71Sopenharmony_ci       },
157e41f4b71Sopenharmony_ci       {
158e41f4b71Sopenharmony_ci           tag: huks.HuksTag.HUKS_TAG_IV,
159e41f4b71Sopenharmony_ci           value: StringToUint8Array(IV),
160e41f4b71Sopenharmony_ci       }
161e41f4b71Sopenharmony_ci   ];
162e41f4b71Sopenharmony_ci   let encryptOptions: huks.HuksOptions = {
163e41f4b71Sopenharmony_ci       properties: propertiesEncrypt,
164e41f4b71Sopenharmony_ci       inData: new Uint8Array(new Array())
165e41f4b71Sopenharmony_ci   }
166e41f4b71Sopenharmony_ci   class throwObject1{
167e41f4b71Sopenharmony_ci       isThrow: boolean = false;
168e41f4b71Sopenharmony_ci   }
169e41f4b71Sopenharmony_ci   function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject1) {
170e41f4b71Sopenharmony_ci       return new Promise<huks.HuksSessionHandle>((resolve, reject) => {
171e41f4b71Sopenharmony_ci           try {
172e41f4b71Sopenharmony_ci               huks.initSession(keyAlias, huksOptions, (error, data) => {
173e41f4b71Sopenharmony_ci                   if (error) {
174e41f4b71Sopenharmony_ci                       reject(error);
175e41f4b71Sopenharmony_ci                   } else {
176e41f4b71Sopenharmony_ci                       resolve(data);
177e41f4b71Sopenharmony_ci                   }
178e41f4b71Sopenharmony_ci               });
179e41f4b71Sopenharmony_ci           } catch (error) {
180e41f4b71Sopenharmony_ci               throwObject.isThrow = true;
181e41f4b71Sopenharmony_ci               throw (error as Error);
182e41f4b71Sopenharmony_ci           }
183e41f4b71Sopenharmony_ci       });
184e41f4b71Sopenharmony_ci   }
185e41f4b71Sopenharmony_ci   async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
186e41f4b71Sopenharmony_ci       console.info(`enter promise doInit`);
187e41f4b71Sopenharmony_ci       let throwObject: throwObject1 = { isThrow: false };
188e41f4b71Sopenharmony_ci       try {
189e41f4b71Sopenharmony_ci           await initSession(keyAlias, huksOptions, throwObject)
190e41f4b71Sopenharmony_ci           .then((data) => {
191e41f4b71Sopenharmony_ci               console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
192e41f4b71Sopenharmony_ci               handle = data.handle as number;
193e41f4b71Sopenharmony_ci           })
194e41f4b71Sopenharmony_ci           .catch((error: Error) => {
195e41f4b71Sopenharmony_ci               if (throwObject.isThrow) {
196e41f4b71Sopenharmony_ci                   throw (error as Error);
197e41f4b71Sopenharmony_ci               } else {
198e41f4b71Sopenharmony_ci                   console.error(`promise: doInit failed` + JSON.stringify(error));
199e41f4b71Sopenharmony_ci               }
200e41f4b71Sopenharmony_ci           });
201e41f4b71Sopenharmony_ci       } catch (error) {
202e41f4b71Sopenharmony_ci           console.error(`promise: doInit input arg invalid` + JSON.stringify(error));
203e41f4b71Sopenharmony_ci       }
204e41f4b71Sopenharmony_ci   }
205e41f4b71Sopenharmony_ci   function finishSession(handle: number, huksOptions: huks.HuksOptions, throwObject: throwObject1) {
206e41f4b71Sopenharmony_ci       return new Promise<huks.HuksReturnResult>((resolve, reject) => {
207e41f4b71Sopenharmony_ci           try {
208e41f4b71Sopenharmony_ci               huks.finishSession(handle, huksOptions, (error, data) => {
209e41f4b71Sopenharmony_ci                   if (error) {
210e41f4b71Sopenharmony_ci                       reject(error);
211e41f4b71Sopenharmony_ci                   } else {
212e41f4b71Sopenharmony_ci                       resolve(data);
213e41f4b71Sopenharmony_ci                   }
214e41f4b71Sopenharmony_ci               });
215e41f4b71Sopenharmony_ci           } catch (error) {
216e41f4b71Sopenharmony_ci               throwObject.isThrow = true;
217e41f4b71Sopenharmony_ci               throw (error as Error);
218e41f4b71Sopenharmony_ci           }
219e41f4b71Sopenharmony_ci       });
220e41f4b71Sopenharmony_ci   }
221e41f4b71Sopenharmony_ci   async function publicFinishFunc(handle: number, huksOptions: huks.HuksOptions) {
222e41f4b71Sopenharmony_ci       console.info(`enter promise doFinish`);
223e41f4b71Sopenharmony_ci       let throwObject: throwObject1 = { isThrow: false };
224e41f4b71Sopenharmony_ci       try {
225e41f4b71Sopenharmony_ci           await finishSession(handle, huksOptions, throwObject)
226e41f4b71Sopenharmony_ci           .then((data) => {
227e41f4b71Sopenharmony_ci               cipherText = data.outData as Uint8Array;
228e41f4b71Sopenharmony_ci               console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
229e41f4b71Sopenharmony_ci           })
230e41f4b71Sopenharmony_ci           .catch((error: Error) => {
231e41f4b71Sopenharmony_ci               if (throwObject.isThrow) {
232e41f4b71Sopenharmony_ci                   throw (error as Error);
233e41f4b71Sopenharmony_ci               } else {
234e41f4b71Sopenharmony_ci                   console.error(`promise: doFinish failed` + JSON.stringify(error));
235e41f4b71Sopenharmony_ci               }
236e41f4b71Sopenharmony_ci           });
237e41f4b71Sopenharmony_ci       } catch (error) {
238e41f4b71Sopenharmony_ci           console.error(`promise: doFinish input arg invalid` + JSON.stringify(error));
239e41f4b71Sopenharmony_ci       }
240e41f4b71Sopenharmony_ci   }
241e41f4b71Sopenharmony_ci   async function testSm4Cipher() {
242e41f4b71Sopenharmony_ci       /* Initialize the key session to obtain a challenge. */
243e41f4b71Sopenharmony_ci       await publicInitFunc(keyAlias, encryptOptions);
244e41f4b71Sopenharmony_ci       /** Encryption */
245e41f4b71Sopenharmony_ci       encryptOptions.inData = StringToUint8Array(cipherInData);
246e41f4b71Sopenharmony_ci       await publicFinishFunc(handle, encryptOptions);
247e41f4b71Sopenharmony_ci   }
248e41f4b71Sopenharmony_ci   ```
249e41f4b71Sopenharmony_ci
250e41f4b71Sopenharmony_ci3. Use the key. User identity authentication is required when the key is used for decryption.
251e41f4b71Sopenharmony_ci   
252e41f4b71Sopenharmony_ci   ```ts
253e41f4b71Sopenharmony_ci    import { huks } from "@kit.UniversalKeystoreKit";
254e41f4b71Sopenharmony_ci    import { userAuth } from '@kit.UserAuthenticationKit';
255e41f4b71Sopenharmony_ci    import { BusinessError } from "@kit.BasicServicesKit"
256e41f4b71Sopenharmony_ci
257e41f4b71Sopenharmony_ci    let keyAlias = 'test_sm4_key_alias';
258e41f4b71Sopenharmony_ci    let IV = '1234567890123456';
259e41f4b71Sopenharmony_ci    let handle = 0;
260e41f4b71Sopenharmony_ci    let cipherText: Uint8Array; // Data in ciphertext.
261e41f4b71Sopenharmony_ci    /*
262e41f4b71Sopenharmony_ci    * Determine the key property set to be encapsulated.
263e41f4b71Sopenharmony_ci    */
264e41f4b71Sopenharmony_ci    let finishOutData: Uint8Array; // Plaintext after decryption.
265e41f4b71Sopenharmony_ci    let fingerAuthToken: Uint8Array;
266e41f4b71Sopenharmony_ci    let challenge: Uint8Array;
267e41f4b71Sopenharmony_ci    let authType = userAuth.UserAuthType.FINGERPRINT;
268e41f4b71Sopenharmony_ci    let authTrustLevel = userAuth.AuthTrustLevel.ATL1;
269e41f4b71Sopenharmony_ci    class throwObject {
270e41f4b71Sopenharmony_ci        isThrow: boolean = false;
271e41f4b71Sopenharmony_ci    }
272e41f4b71Sopenharmony_ci    function StringToUint8Array(str: string) {
273e41f4b71Sopenharmony_ci        let arr: number[] = [];
274e41f4b71Sopenharmony_ci        for (let i = 0, j = str.length; i < j; ++i) {
275e41f4b71Sopenharmony_ci            arr.push(str.charCodeAt(i));
276e41f4b71Sopenharmony_ci        }
277e41f4b71Sopenharmony_ci        return new Uint8Array(arr);
278e41f4b71Sopenharmony_ci    }
279e41f4b71Sopenharmony_ci    /* Set the key generation parameter set and key encryption parameter set. */
280e41f4b71Sopenharmony_ci    class propertyDecryptType {
281e41f4b71Sopenharmony_ci    tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM
282e41f4b71Sopenharmony_ci    value: huks.HuksKeyAlg | huks.HuksKeyPurpose | huks.HuksKeySize | huks.HuksKeyPadding | huks.HuksCipherMode
283e41f4b71Sopenharmony_ci        | Uint8Array = huks.HuksKeyAlg.HUKS_ALG_SM4
284e41f4b71Sopenharmony_ci    }
285e41f4b71Sopenharmony_ci    let propertiesDecrypt: propertyDecryptType[] = [
286e41f4b71Sopenharmony_ci        {
287e41f4b71Sopenharmony_ci            tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
288e41f4b71Sopenharmony_ci            value: huks.HuksKeyAlg.HUKS_ALG_SM4,
289e41f4b71Sopenharmony_ci        },
290e41f4b71Sopenharmony_ci        {
291e41f4b71Sopenharmony_ci            tag: huks.HuksTag.HUKS_TAG_PURPOSE,
292e41f4b71Sopenharmony_ci            value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT,
293e41f4b71Sopenharmony_ci        },
294e41f4b71Sopenharmony_ci        {
295e41f4b71Sopenharmony_ci            tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
296e41f4b71Sopenharmony_ci            value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128,
297e41f4b71Sopenharmony_ci        },
298e41f4b71Sopenharmony_ci        {
299e41f4b71Sopenharmony_ci            tag: huks.HuksTag.HUKS_TAG_PADDING,
300e41f4b71Sopenharmony_ci            value: huks.HuksKeyPadding.HUKS_PADDING_NONE,
301e41f4b71Sopenharmony_ci        },
302e41f4b71Sopenharmony_ci        {
303e41f4b71Sopenharmony_ci            tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
304e41f4b71Sopenharmony_ci            value: huks.HuksCipherMode.HUKS_MODE_CBC,
305e41f4b71Sopenharmony_ci        },
306e41f4b71Sopenharmony_ci        {
307e41f4b71Sopenharmony_ci            tag: huks.HuksTag.HUKS_TAG_IV,
308e41f4b71Sopenharmony_ci            value: StringToUint8Array(IV),
309e41f4b71Sopenharmony_ci        }
310e41f4b71Sopenharmony_ci    ]
311e41f4b71Sopenharmony_ci    let decryptOptions: huks.HuksOptions = {
312e41f4b71Sopenharmony_ci        properties: propertiesDecrypt,
313e41f4b71Sopenharmony_ci        inData: new Uint8Array(new Array())
314e41f4b71Sopenharmony_ci    }
315e41f4b71Sopenharmony_ci    function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) {
316e41f4b71Sopenharmony_ci        return new Promise<huks.HuksSessionHandle>((resolve, reject) => {
317e41f4b71Sopenharmony_ci            try {
318e41f4b71Sopenharmony_ci                huks.initSession(keyAlias, huksOptions, (error, data) => {
319e41f4b71Sopenharmony_ci                    if (error) {
320e41f4b71Sopenharmony_ci                        reject(error);
321e41f4b71Sopenharmony_ci                    } else {
322e41f4b71Sopenharmony_ci                        resolve(data);
323e41f4b71Sopenharmony_ci                    }
324e41f4b71Sopenharmony_ci                });
325e41f4b71Sopenharmony_ci            } catch (error) {
326e41f4b71Sopenharmony_ci                throwObject.isThrow = true;
327e41f4b71Sopenharmony_ci                throw(error as Error);
328e41f4b71Sopenharmony_ci            }
329e41f4b71Sopenharmony_ci        });
330e41f4b71Sopenharmony_ci    }
331e41f4b71Sopenharmony_ci    async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) {
332e41f4b71Sopenharmony_ci    console.info(`enter promise doInit`);
333e41f4b71Sopenharmony_ci    let throwObject: throwObject = {isThrow: false};
334e41f4b71Sopenharmony_ci    try {
335e41f4b71Sopenharmony_ci        await initSession(keyAlias, huksOptions, throwObject)
336e41f4b71Sopenharmony_ci        .then ((data) => {
337e41f4b71Sopenharmony_ci            console.info(`promise: doInit success, data = ${JSON.stringify(data)}`);
338e41f4b71Sopenharmony_ci            handle = data.handle;
339e41f4b71Sopenharmony_ci            challenge = data.challenge as Uint8Array;
340e41f4b71Sopenharmony_ci        })
341e41f4b71Sopenharmony_ci        .catch((error: BusinessError) => {
342e41f4b71Sopenharmony_ci            if (throwObject.isThrow) {
343e41f4b71Sopenharmony_ci            throw(error as Error);
344e41f4b71Sopenharmony_ci            } else {
345e41f4b71Sopenharmony_ci            console.error(`promise: doInit failed` + JSON.stringify(error));
346e41f4b71Sopenharmony_ci            }
347e41f4b71Sopenharmony_ci        });
348e41f4b71Sopenharmony_ci    } catch (error) {
349e41f4b71Sopenharmony_ci        console.error(`promise: doInit input arg invalid` + JSON.stringify(error));
350e41f4b71Sopenharmony_ci    }
351e41f4b71Sopenharmony_ci    }
352e41f4b71Sopenharmony_ci    function userIAMAuthFinger(huksChallenge: Uint8Array) {
353e41f4b71Sopenharmony_ci    // Obtain an authentication object.
354e41f4b71Sopenharmony_ci    let authTypeList:userAuth.UserAuthType[]= [ authType ];
355e41f4b71Sopenharmony_ci    const authParam:userAuth.AuthParam = {
356e41f4b71Sopenharmony_ci        challenge: huksChallenge,
357e41f4b71Sopenharmony_ci        authType: authTypeList,
358e41f4b71Sopenharmony_ci        authTrustLevel: userAuth.AuthTrustLevel.ATL1
359e41f4b71Sopenharmony_ci    };
360e41f4b71Sopenharmony_ci    const widgetParam:userAuth.WidgetParam = {
361e41f4b71Sopenharmony_ci        title: 'Enter password',
362e41f4b71Sopenharmony_ci    };
363e41f4b71Sopenharmony_ci    let auth : userAuth.UserAuthInstance;
364e41f4b71Sopenharmony_ci    try {
365e41f4b71Sopenharmony_ci        auth = userAuth.getUserAuthInstance(authParam, widgetParam);
366e41f4b71Sopenharmony_ci        console.info("get auth instance success");
367e41f4b71Sopenharmony_ci    } catch (error) {
368e41f4b71Sopenharmony_ci        console.error("get auth instance failed" + JSON.stringify(error));
369e41f4b71Sopenharmony_ci        return;
370e41f4b71Sopenharmony_ci    }
371e41f4b71Sopenharmony_ci    // Subscribe to the authentication result.
372e41f4b71Sopenharmony_ci    try {
373e41f4b71Sopenharmony_ci        auth.on("result", {
374e41f4b71Sopenharmony_ci        onResult(result) {
375e41f4b71Sopenharmony_ci            console.info("[HUKS] -> [IAM]  userAuthInstance callback result = " + JSON.stringify(result));
376e41f4b71Sopenharmony_ci            fingerAuthToken = result.token;
377e41f4b71Sopenharmony_ci        }
378e41f4b71Sopenharmony_ci        });
379e41f4b71Sopenharmony_ci        console.info("subscribe authentication event success");
380e41f4b71Sopenharmony_ci    } catch (error) {
381e41f4b71Sopenharmony_ci        console.error("subscribe authentication event failed " + JSON.stringify(error));
382e41f4b71Sopenharmony_ci    }
383e41f4b71Sopenharmony_ci    // Start user authentication.
384e41f4b71Sopenharmony_ci    try {
385e41f4b71Sopenharmony_ci        auth.start();
386e41f4b71Sopenharmony_ci        console.info("authV9 start auth success");
387e41f4b71Sopenharmony_ci    } catch (error) {
388e41f4b71Sopenharmony_ci        console.error("authV9 start auth failed, error = " + JSON.stringify(error));
389e41f4b71Sopenharmony_ci    }
390e41f4b71Sopenharmony_ci    }
391e41f4b71Sopenharmony_ci    function finishSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array, throwObject: throwObject) {
392e41f4b71Sopenharmony_ci    return new Promise<huks.HuksReturnResult>((resolve, reject) => {
393e41f4b71Sopenharmony_ci        try {
394e41f4b71Sopenharmony_ci        huks.finishSession(handle, huksOptions, token, (error, data) => {
395e41f4b71Sopenharmony_ci            if (error) {
396e41f4b71Sopenharmony_ci            reject(error);
397e41f4b71Sopenharmony_ci            } else {
398e41f4b71Sopenharmony_ci            resolve(data);
399e41f4b71Sopenharmony_ci            }
400e41f4b71Sopenharmony_ci        });
401e41f4b71Sopenharmony_ci        } catch (error) {
402e41f4b71Sopenharmony_ci        throwObject.isThrow = true;
403e41f4b71Sopenharmony_ci        throw(error as Error);
404e41f4b71Sopenharmony_ci        }
405e41f4b71Sopenharmony_ci    });
406e41f4b71Sopenharmony_ci    }
407e41f4b71Sopenharmony_ci    async function publicFinishFunc(handle: number, token: Uint8Array, huksOptions: huks.HuksOptions) {
408e41f4b71Sopenharmony_ci    console.info(`enter promise doFinish`);
409e41f4b71Sopenharmony_ci    let throwObject: throwObject = {isThrow: false};
410e41f4b71Sopenharmony_ci    try {
411e41f4b71Sopenharmony_ci        await finishSession(handle, huksOptions, token, throwObject)
412e41f4b71Sopenharmony_ci        .then ((data) => {
413e41f4b71Sopenharmony_ci            finishOutData = data.outData as Uint8Array;
414e41f4b71Sopenharmony_ci            console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`);
415e41f4b71Sopenharmony_ci        })
416e41f4b71Sopenharmony_ci        .catch((error: BusinessError) => {
417e41f4b71Sopenharmony_ci            if (throwObject.isThrow) {
418e41f4b71Sopenharmony_ci                throw(error as Error);
419e41f4b71Sopenharmony_ci            } else {
420e41f4b71Sopenharmony_ci                console.error(`promise: doFinish failed` + JSON.stringify(error));
421e41f4b71Sopenharmony_ci            }
422e41f4b71Sopenharmony_ci        });
423e41f4b71Sopenharmony_ci    } catch (error) {
424e41f4b71Sopenharmony_ci        console.error(`promise: doFinish input arg invalid` + JSON.stringify(error));
425e41f4b71Sopenharmony_ci    }
426e41f4b71Sopenharmony_ci    }
427e41f4b71Sopenharmony_ci    async function testSm4Cipher() {
428e41f4b71Sopenharmony_ci    /* Initialize the key session to obtain a challenge. */
429e41f4b71Sopenharmony_ci    await publicInitFunc(keyAlias, decryptOptions);
430e41f4b71Sopenharmony_ci    /* Invoke userIAM to perform user identity authentication. */
431e41f4b71Sopenharmony_ci    userIAMAuthFinger(challenge);
432e41f4b71Sopenharmony_ci    /* Perform decryption after the authentication is successful. The **authToken** value returned after the authentication needs to be passed in. */
433e41f4b71Sopenharmony_ci    decryptOptions.inData = StringToUint8Array(cipherText);
434e41f4b71Sopenharmony_ci    await publicFinishFunc(handle, fingerAuthToken, decryptOptions);
435e41f4b71Sopenharmony_ci    }
436e41f4b71Sopenharmony_ci   ```
437