1# HUKS Access Control Development 2 3 4For details about scenarios and related concepts, see [HUKS Access Control Overview](huks-identity-authentication-overview.md). 5 6 7## How to Develop 8 91. Generate a key, enable fingerprint authentication for key access, and set related parameters. 10 When a key is generated or imported, set [HuksUserAuthType](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksuserauthtype9), [HuksAuthAccessType](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksauthaccesstype9), and [HuksChallengeType](../../reference/apis-universal-keystore-kit/js-apis-huks.md#hukschallengetype9). 11 12```ts 13import { huks } from '@kit.UniversalKeystoreKit'; 14 15/* 16* Set the key alias and encapsulate the key property set. 17*/ 18let keyAlias = 'test_sm4_key_alias'; 19let properties: Array<huks.HuksParam> = [{ 20 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 21 value: huks.HuksKeyAlg.HUKS_ALG_SM4 22}, { 23 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 24 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT 25}, { 26 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 27 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 28}, { 29 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 30 value: huks.HuksCipherMode.HUKS_MODE_CBC, 31}, { 32 tag: huks.HuksTag.HUKS_TAG_PADDING, 33 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 34}, 35 // Set HuksUserAuthType to fingerprint authentication. 36 { 37 tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE, 38 value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT 39 }, 40 // Set HuksAuthAccessType to HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL, which invalidates the key when a new biometric feature (fingerprint) is enrolled. 41 { 42 tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE, 43 value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL 44 }, 45 // Use the default challenge type. 46 { 47 tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE, 48 value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL 49 }]; 50 51let huksOptions: huks.HuksOptions = { 52 properties: properties, 53 inData: new Uint8Array(new Array()) 54} 55 56/* 57 * Generate a key. 58 */ 59class throwObject { 60 isThrow: boolean = false 61} 62 63function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 64 return new Promise<void>((resolve, reject) => { 65 try { 66 huks.generateKeyItem(keyAlias, huksOptions, (error, data) => { 67 if (error) { 68 reject(error); 69 } else { 70 resolve(data); 71 } 72 }); 73 } catch (error) { 74 throwObject.isThrow = true; 75 throw (error as Error); 76 } 77 }); 78} 79 80async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 81 console.info(`enter promise generateKeyItem`); 82 let throwObject: throwObject = { isThrow: false }; 83 try { 84 await generateKeyItem(keyAlias, huksOptions, throwObject) 85 .then((data) => { 86 console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`); 87 }) 88 .catch((error: Error) => { 89 if (throwObject.isThrow) { 90 throw (error as Error); 91 } else { 92 console.error(`promise: generateKeyItem failed, ` + JSON.stringify(error)); 93 } 94 }); 95 } catch (error) { 96 console.error(`promise: generateKeyItem input arg invalid, ` + JSON.stringify(error)); 97 } 98} 99 100async function TestGenKeyForFingerprintAccessControl() { 101 await publicGenKeyFunc(keyAlias, huksOptions); 102} 103``` 104 1052. Initialize a key session to initiate fingerprint authentication. If the authentication is successful, an authentication token (**AuthToken**) is returned. 106 107```ts 108import { huks } from '@kit.UniversalKeystoreKit'; 109import { userAuth } from '@kit.UserAuthenticationKit'; 110 111/* 112 * Set the key alias and encapsulate the key property set. 113 */ 114let srcKeyAlias = 'test_sm4_key_alias'; 115let handle: number; 116let challenge: Uint8Array; 117let fingerAuthToken: Uint8Array; 118let authType = userAuth.UserAuthType.FINGERPRINT; 119let authTrustLevel = userAuth.AuthTrustLevel.ATL1; 120/* Set the key generation parameter set and key encryption parameter set. */ 121let properties: Array<huks.HuksParam> = [{ 122 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 123 value: huks.HuksKeyAlg.HUKS_ALG_SM4, 124}, { 125 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 126 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, 127}, { 128 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 129 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 130}, { 131 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 132 value: huks.HuksCipherMode.HUKS_MODE_CBC, 133}, { 134 tag: huks.HuksTag.HUKS_TAG_PADDING, 135 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 136}, { 137 tag: huks.HuksTag.HUKS_TAG_IV, 138 value: StringToUint8Array(IV), 139}]; 140 141let huksOptions: huks.HuksOptions = { 142 properties: properties, 143 inData: new Uint8Array(new Array()) 144} 145 146class throwObject { 147 isThrow: boolean = false 148} 149 150function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 151 return new Promise<huks.HuksSessionHandle>((resolve, reject) => { 152 try { 153 huks.initSession(keyAlias, huksOptions, (error, data) => { 154 if (error) { 155 reject(error); 156 } else { 157 resolve(data); 158 } 159 }); 160 } catch (error) { 161 throwObject.isThrow = true; 162 throw (error as Error); 163 } 164 }); 165} 166 167async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 168 console.info(`enter promise doInit`); 169 let throwObject: throwObject = { isThrow: false }; 170 try { 171 await initSession(keyAlias, huksOptions, throwObject) 172 .then((data) => { 173 console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); 174 handle = data.handle; 175 challenge = data.challenge as Uint8Array; 176 }) 177 .catch((error: Error) => { 178 if (throwObject.isThrow) { 179 throw (error as Error); 180 } else { 181 console.error(`promise: doInit failed, ` + JSON.stringify(error)); 182 } 183 }); 184 } catch (error) { 185 console.error(`promise: doInit input arg invalid, ` + JSON.stringify(error)); 186 } 187} 188 189function userIAMAuthFinger(huksChallenge: Uint8Array) { 190 // Obtain an authentication object. 191 let authTypeList: userAuth.UserAuthType[] = [authType]; 192 const authParam: userAuth.AuthParam = { 193 challenge: huksChallenge, 194 authType: authTypeList, 195 authTrustLevel: userAuth.AuthTrustLevel.ATL1 196 }; 197 const widgetParam: userAuth.WidgetParam = { 198 title: 'Enter password', 199 }; 200 let auth: userAuth.UserAuthInstance; 201 try { 202 auth = userAuth.getUserAuthInstance(authParam, widgetParam); 203 console.info("get auth instance success"); 204 } catch (error) { 205 console.error("get auth instance failed" + JSON.stringify(error)); 206 return; 207 } 208 // Subscribe to the authentication result. 209 try { 210 auth.on("result", { 211 onResult(result) { 212 console.info("[HUKS] -> [IAM] userAuthInstance callback result = " + JSON.stringify(result)); 213 fingerAuthToken = result.token; 214 } 215 }); 216 console.log("subscribe authentication event success"); 217 } catch (error) { 218 console.error("subscribe authentication event failed, " + JSON.stringify(error)); 219 } 220 // Start user authentication. 221 try { 222 auth.start(); 223 console.info("authV9 start auth success"); 224 } catch (error) { 225 console.error("authV9 start auth failed, error = " + JSON.stringify(error)); 226 } 227} 228 229async function testInitAndAuthFinger() { 230 /* Initialize the key session to obtain a challenge. */ 231 await publicInitFunc(srcKeyAlias, huksOptions); 232 /* Invoke userIAM to perform user identity authentication. */ 233 userIAMAuthFinger(challenge); 234} 235``` 236 2373. Pass in **AuthToken** to perform data operations. 238 239```ts 240/* 241* The following uses a 128-bit SM4 key as an example. 242*/ 243import { huks } from '@kit.UniversalKeystoreKit'; 244 245/* 246* Determine the key property set to be encapsulated. 247*/ 248let IV = '1234567890123456'; 249let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; 250let handle: number; 251let fingerAuthToken: Uint8Array; 252let finishOutData: Uint8Array; 253 254class throwObject { 255 isThrow: boolean = false; 256} 257 258/* Set the key generation parameter set and key encryption parameter set. */ 259class propertyEncryptType { 260 tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM; 261 value: huks.HuksKeyAlg | huks.HuksKeyPurpose | huks.HuksKeySize | huks.HuksKeyPadding | huks.HuksCipherMode 262 | Uint8Array = huks.HuksKeyAlg.HUKS_ALG_SM4; 263} 264 265let propertiesEncrypt: propertyEncryptType[] = [ 266 { 267 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 268 value: huks.HuksKeyAlg.HUKS_ALG_SM4, 269 }, 270 { 271 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 272 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, 273 }, 274 { 275 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 276 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 277 }, 278 { 279 tag: huks.HuksTag.HUKS_TAG_PADDING, 280 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 281 }, 282 { 283 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 284 value: huks.HuksCipherMode.HUKS_MODE_CBC, 285 }, 286 { 287 tag: huks.HuksTag.HUKS_TAG_IV, 288 value: StringToUint8Array(IV), 289 } 290] 291let encryptOptions: huks.HuksOptions = { 292 properties: propertiesEncrypt, 293 inData: new Uint8Array(new Array()) 294} 295 296function StringToUint8Array(str: string) { 297 let arr: number[] = []; 298 for (let i = 0, j = str.length; i < j; ++i) { 299 arr.push(str.charCodeAt(i)); 300 } 301 return new Uint8Array(arr); 302} 303 304function updateSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array, throwObject: throwObject) { 305 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 306 try { 307 huks.updateSession(handle, huksOptions, token, (error, data) => { 308 if (error) { 309 reject(error); 310 } else { 311 resolve(data); 312 } 313 }); 314 } catch (error) { 315 throwObject.isThrow = true; 316 throw (error as Error); 317 } 318 }); 319} 320 321async function publicUpdateFunc(handle: number, token: Uint8Array, huksOptions: huks.HuksOptions) { 322 console.info(`enter promise doUpdate`); 323 let throwObject: throwObject = { isThrow: false }; 324 try { 325 await updateSession(handle, huksOptions, token, throwObject) 326 .then((data) => { 327 console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`); 328 }) 329 .catch((error: Error) => { 330 if (throwObject.isThrow) { 331 throw (error as Error); 332 } else { 333 console.error(`promise: doUpdate failed, ` + JSON.stringify(error)); 334 } 335 }); 336 } catch (error) { 337 console.error(`promise: doUpdate input arg invalid, ` + JSON.stringify(error)); 338 } 339} 340 341function finishSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array, throwObject: throwObject) { 342 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 343 try { 344 huks.finishSession(handle, huksOptions, token, (error, data) => { 345 if (error) { 346 reject(error); 347 } else { 348 resolve(data); 349 } 350 }); 351 } catch (error) { 352 throwObject.isThrow = true; 353 throw (error as Error); 354 } 355 }); 356} 357 358async function publicFinishFunc(handle: number, token: Uint8Array, huksOptions: huks.HuksOptions) { 359 console.info(`enter promise doFinish`); 360 let throwObject: throwObject = { isThrow: false }; 361 try { 362 await finishSession(handle, huksOptions, token, throwObject) 363 .then((data) => { 364 finishOutData = data.outData as Uint8Array; 365 console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`); 366 }) 367 .catch((error: Error) => { 368 if (throwObject.isThrow) { 369 throw (error as Error); 370 } else { 371 console.error(`promise: doFinish failed, ` + JSON.stringify(error)); 372 } 373 }); 374 } catch (error) { 375 console.error(`promise: doFinish input arg invalid, ` + JSON.stringify(error)); 376 } 377} 378 379async function testSm4Cipher() { 380 encryptOptions.inData = StringToUint8Array(cipherInData); 381 /* Pass in AuthToken. */ 382 await publicUpdateFunc(handle, fingerAuthToken, encryptOptions); 383 /* Pass in AuthToken. */ 384 await publicFinishFunc(handle, fingerAuthToken, encryptOptions); 385 if (finishOutData === StringToUint8Array(cipherInData)) { 386 console.info('test finish encrypt error '); 387 } else { 388 console.info('test finish encrypt success'); 389 } 390} 391``` 392