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