• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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```