1# 用户身份认证访问控制开发指导 2 3场景介绍及相关概念说明请参考[用户身份认证访问控制简介](huks-identity-authentication-overview.md)。 4 5## 开发步骤 6 71. 生成密钥,指定指纹访问控制类型及相关属性。 8 生成或导入密钥时,在密钥属性集中需指定三个参数:用户认证类型[HuksUserAuthType](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksuserauthtype9)、授权访问类型[HuksAuthAccessType](../../reference/apis-universal-keystore-kit/js-apis-huks.md#huksauthaccesstype9)、挑战值类型[HuksChallengeType](../../reference/apis-universal-keystore-kit/js-apis-huks.md#hukschallengetype9)。 9 10```ts 11import { huks } from '@kit.UniversalKeystoreKit'; 12 13/* 14* 确定密钥别名和封装密钥属性参数集 15*/ 16let keyAlias = 'test_sm4_key_alias'; 17let properties: Array<huks.HuksParam> = [{ 18 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 19 value: huks.HuksKeyAlg.HUKS_ALG_SM4 20}, { 21 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 22 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT 23}, { 24 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 25 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 26}, { 27 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 28 value: huks.HuksCipherMode.HUKS_MODE_CBC, 29}, { 30 tag: huks.HuksTag.HUKS_TAG_PADDING, 31 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 32}, 33 // 指定密钥身份认证的类型:指纹。 34 { 35 tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE, 36 value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT 37 }, 38 // 指定密钥安全授权的类型(失效类型):新录入生物特征(指纹)后无效。 39 { 40 tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE, 41 value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL 42 }, 43 // 指定挑战值的类型:默认类型。 44 { 45 tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE, 46 value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL 47 }]; 48 49let huksOptions: huks.HuksOptions = { 50 properties: properties, 51 inData: new Uint8Array(new Array()) 52} 53 54/* 55 * 生成密钥 56 */ 57class throwObject { 58 isThrow: boolean = false 59} 60 61function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 62 return new Promise<void>((resolve, reject) => { 63 try { 64 huks.generateKeyItem(keyAlias, huksOptions, (error, data) => { 65 if (error) { 66 reject(error); 67 } else { 68 resolve(data); 69 } 70 }); 71 } catch (error) { 72 throwObject.isThrow = true; 73 throw (error as Error); 74 } 75 }); 76} 77 78async function publicGenKeyFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 79 console.info(`enter promise generateKeyItem`); 80 let throwObject: throwObject = { isThrow: false }; 81 try { 82 await generateKeyItem(keyAlias, huksOptions, throwObject) 83 .then((data) => { 84 console.info(`promise: generateKeyItem success, data = ${JSON.stringify(data)}`); 85 }) 86 .catch((error: Error) => { 87 if (throwObject.isThrow) { 88 throw (error as Error); 89 } else { 90 console.error(`promise: generateKeyItem failed, ` + JSON.stringify(error)); 91 } 92 }); 93 } catch (error) { 94 console.error(`promise: generateKeyItem input arg invalid, ` + JSON.stringify(error)); 95 } 96} 97 98async function TestGenKeyForFingerprintAccessControl() { 99 await publicGenKeyFunc(keyAlias, huksOptions); 100} 101``` 102 1032. 初始化密钥会话,发起指纹认证获取认证令牌。 104 105```ts 106import { huks } from '@kit.UniversalKeystoreKit'; 107import { userAuth } from '@kit.UserAuthenticationKit'; 108 109/* 110 * 确定密钥别名和封装密钥属性参数集 111 */ 112let IV = '1234567890123456'; // 此处为样例代码,实际使用需采用随机值。 113let srcKeyAlias = 'test_sm4_key_alias'; 114let handle: number; 115let challenge: Uint8Array; 116let fingerAuthToken: Uint8Array; 117let authType = userAuth.UserAuthType.FINGERPRINT; 118let authTrustLevel = userAuth.AuthTrustLevel.ATL1; 119/* 集成生成密钥参数集 & 加密参数集 */ 120let properties: Array<huks.HuksParam> = [{ 121 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 122 value: huks.HuksKeyAlg.HUKS_ALG_SM4, 123}, { 124 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 125 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, 126}, { 127 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 128 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 129}, { 130 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 131 value: huks.HuksCipherMode.HUKS_MODE_CBC, 132}, { 133 tag: huks.HuksTag.HUKS_TAG_PADDING, 134 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 135}, { 136 tag: huks.HuksTag.HUKS_TAG_IV, 137 value: StringToUint8Array(IV), 138}]; 139 140function StringToUint8Array(str: string) { 141 let arr: number[] = []; 142 for (let i = 0, j = str.length; i < j; ++i) { 143 arr.push(str.charCodeAt(i)); 144 } 145 return new Uint8Array(arr); 146} 147 148let huksOptions: huks.HuksOptions = { 149 properties: properties, 150 inData: new Uint8Array(new Array()) 151} 152 153class throwObject { 154 isThrow: boolean = false 155} 156 157function initSession(keyAlias: string, huksOptions: huks.HuksOptions, throwObject: throwObject) { 158 return new Promise<huks.HuksSessionHandle>((resolve, reject) => { 159 try { 160 huks.initSession(keyAlias, huksOptions, (error, data) => { 161 if (error) { 162 reject(error); 163 } else { 164 resolve(data); 165 } 166 }); 167 } catch (error) { 168 throwObject.isThrow = true; 169 throw (error as Error); 170 } 171 }); 172} 173/* 初始化HUKS中的会话,获取挑战值 */ 174async function publicInitFunc(keyAlias: string, huksOptions: huks.HuksOptions) { 175 console.info(`enter promise doInit`); 176 let throwObject: throwObject = { isThrow: false }; 177 try { 178 await initSession(keyAlias, huksOptions, throwObject) 179 .then((data) => { 180 console.info(`promise: doInit success, data = ${JSON.stringify(data)}`); 181 handle = data.handle; 182 challenge = data.challenge as Uint8Array; 183 }) 184 .catch((error: Error) => { 185 if (throwObject.isThrow) { 186 throw (error as Error); 187 } else { 188 console.error(`promise: doInit failed, ` + JSON.stringify(error)); 189 } 190 }); 191 } catch (error) { 192 console.error(`promise: doInit input arg invalid, ` + JSON.stringify(error)); 193 } 194} 195/* 调用UserIAM拉起指纹认证,触发HUKS的访问控制流程 */ 196function userIAMAuthFinger(huksChallenge: Uint8Array) { 197 // 获取认证对象。 198 let authTypeList: userAuth.UserAuthType[] = [authType]; 199 const authParam: userAuth.AuthParam = { 200 challenge: huksChallenge, 201 authType: authTypeList, 202 authTrustLevel: userAuth.AuthTrustLevel.ATL1 203 }; 204 const widgetParam: userAuth.WidgetParam = { 205 title: '请输入密码', 206 }; 207 let auth: userAuth.UserAuthInstance; 208 try { 209 auth = userAuth.getUserAuthInstance(authParam, widgetParam); 210 console.info("get auth instance success"); 211 } catch (error) { 212 console.error("get auth instance failed" + JSON.stringify(error)); 213 return; 214 } 215 // 订阅认证结果。 216 try { 217 auth.on("result", { 218 onResult(result) { 219 console.info("[HUKS] -> [IAM] userAuthInstance callback result = " + JSON.stringify(result)); 220 fingerAuthToken = result.token; 221 } 222 }); 223 console.log("subscribe authentication event success"); 224 } catch (error) { 225 console.error("subscribe authentication event failed, " + JSON.stringify(error)); 226 } 227 // 开始认证。 228 try { 229 auth.start(); 230 console.info("authV9 start auth success"); 231 } catch (error) { 232 console.error("authV9 start auth failed, error = " + JSON.stringify(error)); 233 } 234} 235 236async function testInitAndAuthFinger() { 237 /* 初始化密钥会话获取挑战值 */ 238 await publicInitFunc(srcKeyAlias, huksOptions); 239 /* 调用userIAM进行身份认证 */ 240 userIAMAuthFinger(challenge); 241} 242``` 243 2443. 传入认证令牌进行数据操作。 245 246```ts 247/* 248* 以下以SM4 128密钥为例 249*/ 250import { huks } from '@kit.UniversalKeystoreKit'; 251 252/* 253* 确定封装密钥属性参数集 254*/ 255let IV = '1234567890123456'; // 此处为样例代码,实际使用需采用随机值。 256let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; 257let handle: number; 258let fingerAuthToken: Uint8Array; 259let finishOutData: Uint8Array; 260 261class throwObject { 262 isThrow: boolean = false; 263} 264 265/* 集成生成密钥参数集 & 加密参数集 */ 266class propertyEncryptType { 267 tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM; 268 value: huks.HuksKeyAlg | huks.HuksKeyPurpose | huks.HuksKeySize | huks.HuksKeyPadding | huks.HuksCipherMode 269 | Uint8Array = huks.HuksKeyAlg.HUKS_ALG_SM4; 270} 271 272let propertiesEncrypt: propertyEncryptType[] = [ 273 { 274 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 275 value: huks.HuksKeyAlg.HUKS_ALG_SM4, 276 }, 277 { 278 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 279 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, 280 }, 281 { 282 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 283 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 284 }, 285 { 286 tag: huks.HuksTag.HUKS_TAG_PADDING, 287 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 288 }, 289 { 290 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 291 value: huks.HuksCipherMode.HUKS_MODE_CBC, 292 }, 293 { 294 tag: huks.HuksTag.HUKS_TAG_IV, 295 value: StringToUint8Array(IV), 296 } 297] 298let encryptOptions: huks.HuksOptions = { 299 properties: propertiesEncrypt, 300 inData: new Uint8Array(new Array()) 301} 302 303function StringToUint8Array(str: string) { 304 let arr: number[] = []; 305 for (let i = 0, j = str.length; i < j; ++i) { 306 arr.push(str.charCodeAt(i)); 307 } 308 return new Uint8Array(arr); 309} 310 311function updateSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array, throwObject: throwObject) { 312 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 313 try { 314 huks.updateSession(handle, huksOptions, token, (error, data) => { 315 if (error) { 316 reject(error); 317 } else { 318 resolve(data); 319 } 320 }); 321 } catch (error) { 322 throwObject.isThrow = true; 323 throw (error as Error); 324 } 325 }); 326} 327 328async function publicUpdateFunc(handle: number, token: Uint8Array, huksOptions: huks.HuksOptions) { 329 console.info(`enter promise doUpdate`); 330 let throwObject: throwObject = { isThrow: false }; 331 try { 332 await updateSession(handle, huksOptions, token, throwObject) 333 .then((data) => { 334 console.info(`promise: doUpdate success, data = ${JSON.stringify(data)}`); 335 }) 336 .catch((error: Error) => { 337 if (throwObject.isThrow) { 338 throw (error as Error); 339 } else { 340 console.error(`promise: doUpdate failed, ` + JSON.stringify(error)); 341 } 342 }); 343 } catch (error) { 344 console.error(`promise: doUpdate input arg invalid, ` + JSON.stringify(error)); 345 } 346} 347 348function finishSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array, throwObject: throwObject) { 349 return new Promise<huks.HuksReturnResult>((resolve, reject) => { 350 try { 351 huks.finishSession(handle, huksOptions, token, (error, data) => { 352 if (error) { 353 reject(error); 354 } else { 355 resolve(data); 356 } 357 }); 358 } catch (error) { 359 throwObject.isThrow = true; 360 throw (error as Error); 361 } 362 }); 363} 364 365async function publicFinishFunc(handle: number, token: Uint8Array, huksOptions: huks.HuksOptions) { 366 console.info(`enter promise doFinish`); 367 let throwObject: throwObject = { isThrow: false }; 368 try { 369 await finishSession(handle, huksOptions, token, throwObject) 370 .then((data) => { 371 finishOutData = data.outData as Uint8Array; 372 console.info(`promise: doFinish success, data = ${JSON.stringify(data)}`); 373 }) 374 .catch((error: Error) => { 375 if (throwObject.isThrow) { 376 throw (error as Error); 377 } else { 378 console.error(`promise: doFinish failed, ` + JSON.stringify(error)); 379 } 380 }); 381 } catch (error) { 382 console.error(`promise: doFinish input arg invalid, ` + JSON.stringify(error)); 383 } 384} 385 386async function testSm4Cipher() { 387 encryptOptions.inData = StringToUint8Array(cipherInData); 388 /* 传入认证令牌 */ 389 await publicUpdateFunc(handle, fingerAuthToken, encryptOptions); 390 /* 传入认证令牌 */ 391 await publicFinishFunc(handle, fingerAuthToken, encryptOptions); 392 if (finishOutData === StringToUint8Array(cipherInData)) { 393 console.info('test finish encrypt error '); 394 } else { 395 console.info('test finish encrypt success'); 396 } 397} 398``` 399