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