1# 用户身份认证访问控制开发指导 2 3<!--Kit: Universal Keystore Kit--> 4<!--Subsystem: Security--> 5<!--Owner: @wutiantian-gitee--> 6<!--Designer: @HighLowWorld--> 7<!--Tester: @wxy1234564846--> 8<!--Adviser: @zengyawen--> 9 10场景介绍及相关概念说明请参考[用户身份认证访问控制简介](huks-identity-authentication-overview.md)。 11 12## 开发步骤 13 14### 生成密钥 15 16指定指纹访问控制类型及相关属性。 17 18生成或导入密钥时,在密钥属性集中需指定三个参数:用户认证类型[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)。 19 20```ts 21import { huks } from '@kit.UniversalKeystoreKit'; 22import { BusinessError } from "@kit.BasicServicesKit"; 23 24/* 25 * 确定密钥别名和封装密钥属性参数集。 26 */ 27let keyAlias = 'test_sm4_key_alias'; 28let properties: Array<huks.HuksParam> = [{ 29 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 30 value: huks.HuksKeyAlg.HUKS_ALG_SM4 31 }, { 32 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 33 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT 34 }, { 35 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 36 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 37 }, { 38 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 39 value: huks.HuksCipherMode.HUKS_MODE_CBC, 40 }, { 41 tag: huks.HuksTag.HUKS_TAG_PADDING, 42 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 43 }, { 44 // 指定密钥身份认证的类型:指纹。 45 tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE, 46 value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT 47 }, { 48 // 指定密钥安全授权的类型(失效类型):新录入生物特征(指纹)后无效。 49 tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE, 50 value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL 51 }, { 52 // 指定挑战值的类型:默认类型。 53 tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE, 54 value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL 55 }]; 56 57let huksOptions: huks.HuksOptions = { 58 properties: properties, 59 inData: new Uint8Array(new Array()) 60} 61 62/* 63 * 生成密钥。 64 */ 65async function generateKeyItem(keyAlias: string, huksOptions: huks.HuksOptions) { 66 console.info(`promise: enter generateKeyItem`); 67 try { 68 await huks.generateKeyItem(keyAlias, huksOptions) 69 .then(() => { 70 console.info(`promise: generateKeyItem success`); 71 }).catch((error: BusinessError) => { 72 console.error(`promise: generateKeyItem failed, errCode : ${error.code}, errMsg : ${error.message}`); 73 }) 74 } catch (error) { 75 console.error(`promise: generateKeyItem input arg invalid`); 76 } 77} 78 79async function TestGenKeyForFingerprintAccessControl() { 80 await generateKeyItem(keyAlias, huksOptions); 81} 82``` 83 84### 传入认证令牌 85 86发起指纹认证获取认证令牌,进行数据操作。 87 88```ts 89/* 90 * 以下以SM4 128密钥为例。 91 */ 92import { huks } from '@kit.UniversalKeystoreKit'; 93import { userAuth } from '@kit.UserAuthenticationKit'; 94import { BusinessError } from "@kit.BasicServicesKit"; 95import { cryptoFramework } from '@kit.CryptoArchitectureKit' 96 97/* 98 * 确定密钥别名和封装密钥属性参数集。 99 */ 100let IV = cryptoFramework.createRandom().generateRandomSync(16).data; 101let srcKeyAlias = 'test_sm4_key_alias'; 102let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; 103let handle: number; 104let challenge: Uint8Array; 105let fingerAuthToken: Uint8Array; 106let finishOutData: Uint8Array; 107let authType = userAuth.UserAuthType.FINGERPRINT; 108let authTrustLevel = userAuth.AuthTrustLevel.ATL1; 109/* 集成生成密钥参数集&加密参数集。 */ 110let properties: Array<huks.HuksParam> = [{ 111 tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 112 value: huks.HuksKeyAlg.HUKS_ALG_SM4, 113 }, { 114 tag: huks.HuksTag.HUKS_TAG_PURPOSE, 115 value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, 116 }, { 117 tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 118 value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, 119 }, { 120 tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, 121 value: huks.HuksCipherMode.HUKS_MODE_CBC, 122 }, { 123 tag: huks.HuksTag.HUKS_TAG_PADDING, 124 value: huks.HuksKeyPadding.HUKS_PADDING_NONE, 125 }, { 126 tag: huks.HuksTag.HUKS_TAG_IV, 127 value: IV, 128 } 129]; 130/* 加密参数集。 */ 131let huksOptions: huks.HuksOptions = { 132 properties: properties, 133 inData: new Uint8Array(new Array()) 134} 135 136function StringToUint8Array(str: string) { 137 let arr: number[] = []; 138 for (let i = 0, j = str.length; i < j; ++i) { 139 arr.push(str.charCodeAt(i)); 140 } 141 return new Uint8Array(arr); 142} 143 144function Uint8ArrayToString(fileData: Uint8Array) { 145 let dataString = ''; 146 for (let i = 0; i < fileData.length; i++) { 147 dataString += String.fromCharCode(fileData[i]); 148 } 149 return dataString; 150} 151 152/* 初始化HUKS中的会话,获取挑战值。 */ 153async function initSession(keyAlias: string, huksOptions: huks.HuksOptions) { 154 console.info(`promise: enter initSession`); 155 try { 156 await huks.initSession(keyAlias, huksOptions) 157 .then((data) => { 158 handle = data.handle; 159 if (data.challenge != undefined) { 160 challenge = data.challenge as Uint8Array; 161 } 162 console.info(`promise: initSession success`); 163 }).catch((error: BusinessError) => { 164 console.error(`promise: initSession failed, errCode : ${error.code}, errMsg : ${error.message}`); 165 }) 166 } catch (error) { 167 console.error(`promise: initSession input arg invalid`); 168 } 169} 170 171/* 调用UserIAM拉起指纹认证,触发HUKS的访问控制流程。 */ 172function userIAMAuthFinger(huksChallenge: Uint8Array) { 173 // 获取认证对象。 174 let authTypeList: userAuth.UserAuthType[] = [authType]; 175 const authParam: userAuth.AuthParam = { 176 challenge: huksChallenge, 177 authType: authTypeList, 178 authTrustLevel: userAuth.AuthTrustLevel.ATL1 179 }; 180 const widgetParam: userAuth.WidgetParam = { 181 title: '请输入密码', 182 }; 183 let auth: userAuth.UserAuthInstance; 184 let err: BusinessError; 185 try { 186 auth = userAuth.getUserAuthInstance(authParam, widgetParam); 187 console.info("get auth instance success"); 188 } catch (error) { 189 err = error as BusinessError; 190 console.error(`get auth instance failed, errCode : ${err.code}, errMsg : ${err.message}`); 191 return; 192 } 193 // 订阅认证结果。 194 try { 195 auth.on("result", { 196 onResult(result) { 197 console.info(`[HUKS] -> [IAM] userAuthInstance callback result = 198 ${result.result}, ${result.token}, ${result.authType}, ${result.enrolledState}`); 199 fingerAuthToken = result.token; 200 } 201 }); 202 console.log("subscribe authentication event success"); 203 } catch (error) { 204 err = error as BusinessError; 205 console.error(`subscribe authentication event failed, errCode : ${err.code}, errMsg : ${err.message}`); 206 } 207 // 开始认证。 208 try { 209 auth.start(); 210 console.info("authV9 start auth success"); 211 } catch (error) { 212 err = error as BusinessError; 213 console.error(`authV9 start auth failed, errCode : ${err.code}, errMsg : ${err.message}`); 214 } 215} 216 217async function updateSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array) { 218 console.info(`enter promise doUpdate`); 219 try { 220 await huks.updateSession(handle, huksOptions, token) 221 .then((data) => { 222 let outData = data.outData as Uint8Array; 223 console.info(`promise: updateSession success, data = ${Uint8ArrayToString(outData)}`); 224 }).catch((error: BusinessError) => { 225 console.error(`promise: updateSession failed, errCode : ${error.code}, errMsg : ${error.message}`); 226 }) 227 } catch (error) { 228 console.error(`promise: updateSession input arg invalid`); 229 } 230} 231 232async function finishSession(handle: number, huksOptions: huks.HuksOptions, token: Uint8Array) { 233 console.info(`enter promise doFinish`); 234 try { 235 await huks.finishSession(handle, huksOptions, token) 236 .then((data) => { 237 finishOutData = data.outData as Uint8Array; 238 console.info(`promise: finishSession success, data = ${Uint8ArrayToString(finishOutData)}`); 239 }).catch((error: BusinessError) => { 240 console.error(`promise: finishSession failed, errCode : ${error.code}, errMsg : ${error.message}`); 241 }) 242 } catch (error) { 243 console.error(`promise: finishSession input arg invalid`); 244 } 245} 246 247/* 进行数据操作。 */ 248async function testSm4Cipher() { 249 huksOptions.inData = StringToUint8Array(cipherInData); 250 /* 传入认证令牌。 */ 251 await updateSession(handle, huksOptions, fingerAuthToken); 252 /* 传入认证令牌。 */ 253 await finishSession(handle, huksOptions, fingerAuthToken); 254 if (Uint8ArrayToString(finishOutData) == cipherInData) { 255 console.info('test finish encrypt error '); 256 } else { 257 console.info('test finish encrypt success'); 258 } 259} 260 261async function testAuthControl() { 262 /* 初始化密钥会话获取挑战值。 */ 263 await initSession(srcKeyAlias, huksOptions); 264 /* 调用userIAM进行身份认证。 */ 265 /* 需要在超时10秒之前完成指纹认证。 */ 266 userIAMAuthFinger(challenge); 267 setTimeout(() => { 268 testSm4Cipher(); 269 }, 10 * 1000); 270} 271```