diff --git a/en/application-dev/reference/apis/js-apis-huks.md b/en/application-dev/reference/apis/js-apis-huks.md index 085a1da52c3b233db29b04738eeea3bb8e532594..11c2f8d4ea97dbc0149b68b6eea7b873ba8eeefb 100644 --- a/en/application-dev/reference/apis/js-apis-huks.md +++ b/en/application-dev/reference/apis/js-apis-huks.md @@ -77,6 +77,25 @@ Generates a key. This API uses an asynchronous callback to return the result. | options | [HuksOptions](#huksoptions) | Yes | Tags required for generating the key. The algorithm, key purpose, and key length are mandatory.| | callback | AsyncCallback\ | Yes | Callback invoked to return the result. If no error is captured, the key is successfully generated. In this case, the API does not return the key content because the key is always protected in a TEE. If an error is captured, an exception occurs in the generation process.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000012 | external error. | +| 12000013 | queried credential does not exist. | +| 12000014 | memory is insufficient. | +| 12000015 | call service failed. | + **Example** ```js @@ -132,6 +151,25 @@ Generates a key. This API uses a promise to return the result. Because the key i | keyAlias | string | Yes | Alias of the key. | | options | [HuksOptions](#huksoptions) | Yes | Tags required for generating the key. The algorithm, key purpose, and key length are mandatory.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000012 | external error. | +| 12000013 | queried credential does not exist. | +| 12000014 | memory is insufficient. | +| 12000015 | call service failed. | + **Example** ```js @@ -188,6 +226,20 @@ Deletes a key. This API uses an asynchronous callback to return the result. | options | [HuksOptions](#huksoptions) | Yes | Empty object (leave this parameter empty). | | callback | AsyncCallback\ | Yes | Callback invoked to return the result. If the operation is successful, no **err** value is returned; otherwise, an error code is returned.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -224,6 +276,20 @@ Deletes a key. This API uses a promise to return the result. | keyAlias | string | Yes | Key alias passed in when the key was generated.| | options | [HuksOptions](#huksoptions) | Yes | Empty object (leave this parameter empty). | +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -291,6 +357,26 @@ Imports a key in plaintext. This API uses an asynchronous callback to return the | options | [HuksOptions](#huksoptions) | Yes | Tags required for the import and key to import. The algorithm, key purpose, and key length are mandatory.| | callback | AsyncCallback\ | Yes | Callback invoked to return the result. If the operation is successful, no **err** value is returned; otherwise, an error code is returned.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000013 | queried credential does not exist. | +| 12000014 | memory is insufficient. | +| 12000015 | call service failed. | + **Example** ```js @@ -358,6 +444,26 @@ Imports a key in plaintext. This API uses a promise to return the result. | keyAlias | string | Yes | Alias of the key. | | options | [HuksOptions](#huksoptions) | Yes | Tags required for the import and key to import. The algorithm, key purpose, and key length are mandatory.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000013 | queried credential does not exist. | +| 12000014 | memory is insufficient. | +| 12000015 | call service failed. | + **Example** ```js @@ -428,6 +534,25 @@ Obtains the certificate used to verify a key. This API uses an asynchronous call | options | [HuksOptions](#huksoptions) | Yes | Parameters and data required for obtaining the certificate. | | callback | AsyncCallback<[HuksReturnResult](#huksreturnresult9)> | Yes | Callback invoked to return the result. If the operation is successful, no **err** value is returned; otherwise, an error code is returned.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 201 | check permission failed. | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -555,6 +680,25 @@ Obtains the certificate used to verify a key. This API uses a promise to return | ---------------------------------------------- | --------------------------------------------- | | Promise<[HuksReturnResult](#huksreturnresult9)> | Promise used to return the result. If the operation is successful, no **err** value is returned; otherwise, an error code is returned.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 201 | check permission failed. | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -678,6 +822,26 @@ Imports a wrapped key. This API uses an asynchronous callback to return the resu | options | [HuksOptions](#huksoptions) | Yes | Tags required for the import and the wrapped key to import. The algorithm, key purpose, and key length are mandatory.| | callback | AsyncCallback\ | Yes | Callback invoked to return the result. If the operation is successful, no **err** value is returned; otherwise, an error code is returned.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000013 | queried credential does not exist. | +| 12000014 | memory is insufficient. | +| 12000015 | call service failed. | + **Example** ```js @@ -893,6 +1057,26 @@ Imports a wrapped key. This API uses a promise to return the result. | wrappingKeyAlias | string | Yes | Alias of the data used to unwrap the key imported. | | options | [HuksOptions](#huksoptions) | Yes | Tags required for the import and the wrapped key to import. The algorithm, key purpose, and key length are mandatory.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000013 | queried credential does not exist. | +| 12000014 | memory is insufficient. | +| 12000015 | call service failed. | + **Example** ```js @@ -928,6 +1112,24 @@ Exports a key. This API uses an asynchronous callback to return the result. | options | [HuksOptions](#huksoptions) | Yes | Empty object (leave this parameter empty). | | callback | AsyncCallback<[HuksReturnResult](#huksreturnresult9)> | Yes | Callback invoked to return the result. If the operation is successful, no **err** value is returned; otherwise, an error code is returned. **outData** contains the public key exported.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -970,6 +1172,24 @@ Exports a key. This API uses a promise to return the result. | ---------------------------------------------- | ------------------------------------------------------------ | | Promise<[HuksReturnResult](#huksreturnresult9)> | Promise used to return the result. If the operation is successful, no **err** value is returned and **outData** contains the public key exported. If the operation fails, an error code is returned. | +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -1007,6 +1227,24 @@ Obtains key properties. This API uses an asynchronous callback to return the res | options | [HuksOptions](#huksoptions) | Yes | Empty object (leave this parameter empty). | | callback | AsyncCallback<[HuksReturnResult](#huksreturnresult9)> | Yes | Callback invoked to return the result. If the operation is successful, no **err** value is returned and **properties** contains the parameters required for generating the key. If the operation fails, an error code is returned. | +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -1049,6 +1287,24 @@ Obtains key properties. This API uses a promise to return the result. | ----------------------------------------------- | ------------------------------------------------------------ | | Promise\<[HuksReturnResult](#huksreturnresult9)> | Promise used to return the result. If the operation is successful, no **err** value is returned and **properties** contains the parameters required for generating the key. If the operation fails, an error code is returned. | +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -1086,9 +1342,28 @@ Checks whether a key exists. This API uses an asynchronous callback to return th | options | [HuksOptions](#huksoptions) | Yes | Empty object (leave this parameter empty). | | callback | AsyncCallback\ | Yes | Callback invoked to return the result. If the key exists, **data** is **true**. If the key does not exist, **error** is the error code.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js +import huks from '@ohos.security.huks'; +import promptAction from '@ohos.promptAction'; + /* Set options to emptyOptions. */ let keyAlias = 'keyAlias'; let emptyOptions = { @@ -1130,9 +1405,28 @@ Checks whether a key exists. This API uses a promise to return the result. | ----------------- | --------------------------------------- | | Promise\ | Promise used to return the result. If the key exists, then() performs subsequent operations. If the key does not exist, error() performs the related service operations.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js +import huks from '@ohos.security.huks'; +import promptAction from '@ohos.promptAction'; + /* Set options to emptyOptions. */ let keyAlias = 'keyAlias'; let emptyOptions = { @@ -1167,6 +1461,25 @@ Initializes the data for a key operation. This API uses an asynchronous callback | options | [HuksOptions](#huksoptions) | Yes | Parameter set used for the **initSession** operation. | | callback | AsyncCallback\<[HuksSessionHandle](#hukssessionhandle9)> | Yes | Callback invoked to return a session handle for subsequent operations.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000010 | the number of sessions has reached limit. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + ## huks.initSession9+ initSession(keyAlias: string, options: HuksOptions) : Promise\ @@ -1188,6 +1501,25 @@ Initializes the data for a key operation. This API uses a promise to return the | ----------------------------------- | -------------------------------------------------- | | Promise\<[HuksSessionHandle](#hukssessionhandle9)> | Promise used to return a session handle for subsequent operations.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000010 | the number of sessions has reached limit. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + ## huks.updateSession9+ updateSession(handle: number, options: HuksOptions, callback: AsyncCallback\) : void @@ -1204,6 +1536,26 @@ Updates the key operation by segment. This API uses an asynchronous callback to | options | [HuksOptions](#huksoptions) | Yes | Parameter set used for the **updateSession** operation. | | callback | AsyncCallback<[HuksReturnResult](#huksreturnresult9)> | Yes | Callback invoked to return the **updateSession** operation result.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000007 | this credential is already invalidated permanently. | +| 12000008 | verify authtoken failed. | +| 12000009 | authtoken is already timeout. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | ## huks.updateSession9+ @@ -1222,6 +1574,27 @@ Updates the key operation by segment. This API uses an asynchronous callback to | token | Uint8Array | Yes | Token of the **updateSession** operation. | | callback | AsyncCallback<[HuksReturnResult](#huksreturnresult9)> | Yes | Callback invoked to return the **updateSession** operation result.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000007 | this credential is already invalidated permanently. | +| 12000008 | verify authtoken failed. | +| 12000009 | authtoken is already timeout. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + ## huks.updateSession9+ updateSession(handle: number, options: HuksOptions, token?: Uint8Array) : Promise\ @@ -1244,6 +1617,27 @@ Updates the key operation by segment. This API uses a promise to return the resu | ----------------------------------- | -------------------------------------------------- | | Promise<[HuksReturnResult](#huksreturnresult9)> | Promise used to return the **updateSession** operation result.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000007 | this credential is already invalidated permanently. | +| 12000008 | verify authtoken failed. | +| 12000009 | authtoken is already timeout. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + ## huks.finishSession9+ finishSession(handle: number, options: HuksOptions, callback: AsyncCallback\) : void @@ -1261,6 +1655,27 @@ Completes the key operation and releases resources. This API uses an asynchronou | token | Uint8Array | Yes | Token of the **finishSession** operation. | | callback | AsyncCallback<[HuksReturnResult](#huksreturnresult9)> | Yes | Callback invoked to return the **finishSession** operation result.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000007 | this credential is already invalidated permanently. | +| 12000008 | verify authtoken failed. | +| 12000009 | authtoken is already timeout. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + ## huks.finishSession9+ finishSession(handle: number, options: HuksOptions, token: Uint8Array, callback: AsyncCallback\) : void @@ -1278,6 +1693,27 @@ Completes the key operation and releases resources. This API uses an asynchronou | token | Uint8Array | Yes | Token of the **finishSession** operation. | | callback | AsyncCallback\<[HuksReturnResult](#huksreturnresult9)> | Yes | Callback invoked to return the **finishSession** operation result.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000007 | this credential is already invalidated permanently. | +| 12000008 | verify authtoken failed. | +| 12000009 | authtoken is already timeout. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + ## huks.finishSession9+ finishSession(handle: number, options: HuksOptions, token?: Uint8Array) : Promise\ @@ -1300,6 +1736,27 @@ Completes the key operation and releases resources. This API uses a promise to r | ----------------------------------- | -------------------------------------------------- | | Promise\<[HuksReturnResult](#huksreturnresult9)> | Promise used to return the result.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000001 | algorithm mode is not supported. | +| 12000002 | algorithm param is missing. | +| 12000003 | algorithm param is invalid. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000007 | this credential is already invalidated permanently. | +| 12000008 | verify authtoken failed. | +| 12000009 | authtoken is already timeout. | +| 12000011 | queried entity does not exist. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + ## huks.abortSession9+ abortSession(handle: number, options: HuksOptions, callback: AsyncCallback\) : void @@ -1316,6 +1773,20 @@ Aborts a key operation. This API uses an asynchronous callback to return the res | options | [HuksOptions](#huksoptions) | Yes | Parameter set used for the **abortSession** operation. | | callback | AsyncCallback\ | Yes | Callback that returns no value. | +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -1466,6 +1937,20 @@ Aborts a key operation. This API uses a promise to return the result. | ----------------------------------- | -------------------------------------------------- | | Promise\ | Promise used to return the **abortSession** operation result.| +**Error codes** + +For details about the error codes, see [HUKS Error Codes](../errorcodes/errorcode-huks.md). + +| ID| Error Message | +| -------- | ------------- | +| 401 | argument is invalid. | +| 801 | api is not supported. | +| 12000004 | operating file failed. | +| 12000005 | IPC communication failed. | +| 12000006 | error occured in crypto engine. | +| 12000012 | external error. | +| 12000014 | memory is insufficient. | + **Example** ```js @@ -1773,10 +2258,12 @@ Enumerates the key storage modes. **System capability**: SystemCapability.Security.Huks -| Name | Value | Description | -| ----------------------- | ---- | ------------------------------ | -| HUKS_STORAGE_TEMP | 0 | The key is managed locally. | -| HUKS_STORAGE_PERSISTENT | 1 | The key is managed by the HUKS service.| +| Name | Value | Description | +| -------------------------------------------- | ---- | ------------------------------ | +| HUKS_STORAGE_TEMP | 0 | The key is managed locally. | +| HUKS_STORAGE_PERSISTENT | 1 | The key is managed by the HUKS service.| +| HUKS_STORAGE_ONLY_USED_IN_HUKS10+ | 2 | The key is stored only in the HUKS. | +| HUKS_STORAGE_KEY_EXPORT_ALLOWED10+ | 3 | The key is exported from the HUKS and is not stored.| ## HuksSendType @@ -1812,6 +2299,17 @@ Enumerates the types of keys to import. By default, a public key is imported. Th | HUKS_KEY_TYPE_PRIVATE_KEY | 1 | Private key | | HUKS_KEY_TYPE_KEY_PAIR | 2 | Public and private key pair| +## HuksRsaPssSaltLenType10+ + +Enumerates the **salt_len** types to set when PSS padding is used in RSA signing or signature verification. + +**System capability**: SystemCapability.Security.Huks + +| Name | Value | Description | +| ------------------------------------------ | ---- | ---------------------------- | +| HUKS_RSA_PSS_SALT_LEN_DIGEST10+ | 0 | **salt_len** is set to the digest length.| +| HUKS_RSA_PSS_SALT_LEN_MAX10+ | 1 | **salt_len** is set to the maximum length.| + ## HuksUserAuthType9+ Enumerates the user authentication types. @@ -1920,6 +2418,8 @@ Enumerates the tags used to invoke parameters. | HUKS_TAG_DERIVE_KEY_SIZE | HuksTagType.HUKS_TAG_TYPE_UINT \| 24 | Size of the derived key. | | HUKS_TAG_IMPORT_KEY_TYPE9+ | HuksTagType.HUKS_TAG_TYPE_UINT \| 25 | Type of the imported key. | | HUKS_TAG_UNWRAP_ALGORITHM_SUITE9+ | HuksTagType.HUKS_TAG_TYPE_UINT \| 26 | Algorithm suite required for encrypted imports. | +| HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG10+ | HuksTagType.HUKS_TAG_TYPE_UINT \|29 | Storage type of the derived key or agreed key.| +| HUKS_TAG_RSA_PSS_SALT_LEN_TYPE10+ | HuksTagType.HUKS_TAG_TYPE_UINT \|30 | Type of the **rsa_pss_salt_length**.| | HUKS_TAG_ACTIVE_DATETIME(deprecated) | HuksTagType.HUKS_TAG_TYPE_ULONG \| 201 | Parameter originally reserved for certificate management. It is deprecated because certificate management is no longer implemented in this module. | | HUKS_TAG_ORIGINATION_EXPIRE_DATETIME(deprecated) | HuksTagType.HUKS_TAG_TYPE_ULONG \| 202 | Parameter originally reserved for certificate management. It is deprecated because certificate management is no longer implemented in this module. | | HUKS_TAG_USAGE_EXPIRE_DATETIME(deprecated) | HuksTagType.HUKS_TAG_TYPE_ULONG \| 203 | Parameter originally reserved for certificate management. It is deprecated because certificate management is no longer implemented in this module. | @@ -1934,6 +2434,7 @@ Enumerates the tags used to invoke parameters. | HUKS_TAG_KEY_SECURE_SIGN_TYPE9+ | HuksTagType.HUKS_TAG_TYPE_UINT \| 308 | Signature type of the key generated or imported.| | HUKS_TAG_CHALLENGE_TYPE9+ | HuksTagType.HUKS_TAG_TYPE_UINT \| 309 | Type of the challenge generated for a key. For details, see [HuksChallengeType](#hukschallengetype9).| | HUKS_TAG_CHALLENGE_POS9+ | HuksTagType.HUKS_TAG_TYPE_UINT \| 310 | Position of the 8-byte valid value in a custom challenge. For details, see [HuksChallengePosition](#hukschallengeposition9).| +| HUKS_TAG_KEY_AUTH_PURPOSE10+ | HuksTagType.HUKS_TAG_TYPE_UINT \|311 | Key authentication purpose.| | HUKS_TAG_ATTESTATION_CHALLENGE | HuksTagType.HUKS_TAG_TYPE_BYTES \| 501 | Challenge value used in the attestation. | | HUKS_TAG_ATTESTATION_APPLICATION_ID | HuksTagType.HUKS_TAG_TYPE_BYTES \| 502 | Application ID used in the attestation. | | HUKS_TAG_ATTESTATION_ID_BRAND | HuksTagType.HUKS_TAG_TYPE_BYTES \| 503 | Brand of the device. | diff --git a/en/application-dev/security/huks-guidelines.md b/en/application-dev/security/huks-guidelines.md index c23e9146f3f9e1a10206a003001339efa63f7444..60839bf7b35ee9043fa8fb70c140459e51d6356f 100644 --- a/en/application-dev/security/huks-guidelines.md +++ b/en/application-dev/security/huks-guidelines.md @@ -3,25 +3,22 @@ ## Key Generation -The HUKS provides the capability of randomly generating keys for services. For a key generated by the HUKS, the plaintext will never be exposed outside throughout the lifecycle. No one can access the plaintext of the key. Even the service, for which the key is generated, can call APIs provided by the HUKS to perform operations on the key and obtain the operation result, but not access the key. +The OpenHarmony Universal KeyStore (HUKS) provides key management and cryptography operations for services. For a key generated by the HUKS, the plaintext will never be exposed outside throughout the lifecycle. No one can obtain the key in plaintext. Even the service itself can call APIs provided by the HUKS to perform operations on the key and obtain the operation result, but cannot access the key. -**How to Develop** +**How to Develop** Use [huks.generateKeyItem(keyAlias,options,callback)](../reference/apis/js-apis-huks.md#huksgeneratekeyitem9) to generate a key. You need to pass in the key alias in **keyAlias**, key property set in **options**, and **callback** to return the result asynchronously. For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). **Procedure** - -1. Determine the key alias. +1. Set the key alias. 2. Initialize the key property set.
Use [HuksParam](../reference/apis/js-apis-huks.md#huksparam) to encapsulate key properties and use a **HuksParam** array to assign values to the **properties** field of [HuksOptions](../reference/apis/js-apis-huks.md#huksoptions). The parameters [HuksKeyAlg](../reference/apis/js-apis-huks.md#hukskeyalg), [HuksKeySize](../reference/apis/js-apis-huks.md#hukskeysize), and [HuksKeyPurpose](../reference/apis/js-apis-huks.md#hukskeypurpose) are mandatory. 3. Pass in the key alias and key parameter set to generate a key. - - > **NOTE** > > The key alias cannot exceed 64 bytes. -**Sample Code** +**Sample code** ```ts /* @@ -30,7 +27,7 @@ Use [huks.generateKeyItem(keyAlias,options,callback)](../reference/apis/js-apis- import huks from '@ohos.security.huks'; /* - * Determine the key alias and encapsulate the key properties. + * Set the key alias and encapsulate the key properties. */ let keyAlias = 'dh_key'; let properties = new Array(); @@ -96,25 +93,20 @@ async function TestGenKey() { ``` ## Key Import -A key generated outside the HUKS (for example, generated through key agreement or by a server) can be imported to the HUKS for management. The HUKS supports import of keys in plaintext. However, if a key is imported in plaintext, the key is exposed in the REE memory. This operation applies to lightweight devices or security-insensitive services. For security-sensitive services, use the secure import provided by the HUKS. Secure import allows the keys generated for services to be transferred to the HUKS through an end-to-end encrypted transmission channel. - -Once a key is imported to the HUKS, its plaintext will not be exposed outside the HUKS throughout the lifecycle of the key. +A key generated outside the HUKS (for example, generated through key agreement or by a server) can be imported to the HUKS for management. The HUKS supports import of keys in plaintext. However, if a key is imported in plaintext, the key is exposed in the Rich Execution Environment (REE) memory. This type of import applies to lightweight devices or security-insensitive services. For security-sensitive services, use the secure import feature provided by the HUKS. Secure import allows the keys generated for services to be transferred to the HUKS through an end-to-end encrypted transmission channel. +Once a key is imported to the HUKS, its plaintext will never be exposed outside the HUKS throughout the lifecycle of the key. ### Importing a Key in Plaintext - Use [huks.importKeyItem(keyAlias,options,callback)](../reference/apis/js-apis-huks.md#huksimportkeyitem9) to import a key in plaintext. You need to pass in the key alias in **keyAlias**, key material and property set in **options**, and **callback** to return the result asynchronously. For details about the APIs, see [HUKS](../reference/apis/js-apis-huks.md). - -1. Determine the key alias. +1. Set the key alias. 2. Encapsulate the key material and key property set.
The key material must comply with [HUKS key material formats](./huks-appendix.md#key-material-formats). The **inData** value of [HuksOptions](../reference/apis/js-apis-huks.md#huksoptions) must be in the Uint8Array format. Encapsulate key properties in [HuksParam](../reference/apis/js-apis-huks.md#huksparam), and use a **HuksParam** array to assign values to the **properties** field. The key properties must contain [HuksKeyAlg](../reference/apis/js-apis-huks.md#hukskeyalg), [HuksKeySize](../reference/apis/js-apis-huks.md#hukskeysize), and [HuksKeyPurpose](../reference/apis/js-apis-huks.md#hukskeypurpose). 3. Import the key. - - -**Sample Code** +**Sample code** ```ts /* @@ -128,7 +120,7 @@ let plainTextSize32 = new Uint8Array([ ]); /* - * Determine the key alias. + * Set the key alias. */ let keyAlias = 'AES256Alias_sample'; @@ -174,7 +166,7 @@ try { Check whether the key exists. If yes, the key is imported successfully. -**Sample Code** +**Sample code** ```ts import huks from '@ohos.security.huks'; @@ -209,26 +201,28 @@ try { ### Importing a Key Securely -Compared with import of plaintext, secure import involves complex key material and operations. The following figure illustrates the basic development process of secure import. +Compared with import of a key in plaintext, secure import involves more complex key material and operations. The following figure illustrates the basic development process of secure import. -**Figure 1** Secure import process +**Figure 1** Development process of secure import ![huks_import_wrapped_key](figures/huks_import_wrapped_key.png) +**Available APIs** +You need to use the APIs listed in the following table in sequence. +**Table 1** APIs for importing a key securely -**Available APIs** - -You need to use the APIs for generating a key, exporting a public key, importing a wrapped key, and deleting a key in sequence. | API | Description | | -------------------------------------- | ----------------------------| |generateKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\) : void| Generates a key.| -|exportKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback) : void| Exports the public key of a key pair.| -|importWrappedKeyItem(keyAlias: string, wrappingKeyAlias: string, options: HuksOptions, callback: AsyncCallback) : void|Imports a wrapped key.| -|deleteKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback) : void|Deletes a key.| +|exportKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\) : void| Exports the public key of a key pair.| +|importWrappedKeyItem(keyAlias: string, wrappingKeyAlias: string, options: HuksOptions, callback: AsyncCallback\) : void|Imports a encrypted key.| +|deleteKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\) : void|Deletes a key.| ->**NOTE**
The public key plaintext material returned by **exportKeyItem()** is encapsulated in X.509 format, and the key material to be imported by **importWrappedKeyItem()** must be encapsulated in **LengthData-Data** format. Specifically, the application needs to request a Uint8Array and encapsulate the Uint8Array in the sequence listed in the following table. +>**NOTE** +> +>The public key plaintext material returned by **exportKeyItem()** is encapsulated in X.509 format, and the key material to be imported by **importWrappedKeyItem()** must be encapsulated in **LengthData-Data** format. Specifically, the application needs to request a Uint8Array and encapsulate the Uint8Array in the sequence listed in the following table. **Table 2** Format of the wrapped key material @@ -245,6 +239,7 @@ You need to use the APIs for generating a key, exporting a public key, importing **How to Develop** The following example presents the development involving HUKS APIs (using the ECDH key agreement suite). The operations performed by the service are not included. + 1. Convert the key material into the HUKS format. 2. Generate a key for secure import. 3. Export the public key material. @@ -261,7 +256,7 @@ The following example presents the development involving HUKS APIs (using the EC import huks from '@ohos.security.huks'; /* - * Determine the key alias. + * Set the key alias. */ let importAlias = "importAlias"; let wrapAlias = "wrappingKeyAlias"; @@ -591,13 +586,13 @@ async function ImportWrappedKeyNormalTest() { Check whether the key exists. If yes, the key is imported successfully. -**Sample Code** +**Sample code** ```ts import huks from '@ohos.security.huks'; /* - * Determine the key alias and encapsulate the key properties. + * Set the key alias and encapsulate the key properties. */ let keyAlias = 'importAlias'; let isKeyExist; @@ -627,7 +622,6 @@ try { } ``` - ## Common Key Operations **When to Use** @@ -637,11 +631,19 @@ To ensure data confidentiality and integrity, you may need to encrypt or decrypt **General Development Process** The HUKS operates data based on key sessions. The general process is as follows: -1. (Mandatory) Use [huks.initSession()](../reference/apis/js-apis-huks.md#huksinitsession9) to initialize a key session.
You need to pass in the key alias and key operation parameters to initialize a key session, and obtain the session handle. The key operation parameters must contain the parameters required by the cipher algorithm, including the cipher algorithm, key size, key purpose, working mode, padding mode, hash mode, IV, nonce, and AAD. If access control is set for the key, other parameters are required. For details, see [Key Access Control](#key-access-control). This step is mandatory. -2. (Optional) Use [huks.updateSession()](../reference/apis/js-apis-huks.md#huksupdatesession9) to pass in data by segment. Perform this step only if the data exceeds 100 KB or the cryptographic algorithm requires operations by data segment. Otherwise, skip this step. This step is optional. -3. (Mandatory) Use [huks.finishSession()](../reference/apis/js-apis-huks.md#huksfinishsession9) to finalize the key session operation.
Pass in the last data segment and perform the key session operation. If an error occurs during the process or the data passed in is not required, use [huks.abortSession()](../reference/apis/js-apis-huks.md#huksabortsession9) to abort the session. This step is mandatory. + +1. (Mandatory) Use [huks.initSession()](../reference/apis/js-apis-huks.md#huksinitsession9) to initialize a key session. + + You need to pass in the key alias and key operation parameters to initialize a key session, and obtain the session handle. The key operation parameters must contain the parameters required by the cipher algorithm, including the cipher algorithm, key size, key purpose, working mode, padding mode, hash mode, IV, nonce, and AAD. If access control is set for the key, other parameters are required. For details, see [Key Access Control](#key-access-control). + +2. (Optional) Use [huks.updateSession()](../reference/apis/js-apis-huks.md#huksupdatesession9) to pass in data by segment. Perform this step only if the data exceeds 100 KB or the cryptographic algorithm requires operations by data segment. Otherwise, skip this step. + +3. (Mandatory) Use [huks.finishSession()](../reference/apis/js-apis-huks.md#huksfinishsession9) to complete the key session operation. + + Pass in the last data segment and complete the key session operation. If an error occurs during the process or the data passed in is not required, use [huks.abortSession()](../reference/apis/js-apis-huks.md#huksabortsession9) to abort the session. ### Encryption and Decryption + ```ts /* * The following uses an AES 128-bit key and callback-based APIs as an example. @@ -958,6 +960,9 @@ struct Index { ``` ### Key Agreement + +You are advised to pass in [HuksKeyStorageType](../reference/apis/js-apis-huks.md#hukskeystoragetype) to specify the storage type in key agreement. From API version 10, only **HUKS_STORAGE_ONLY_USED_IN_HUKS** or **HUKS_STORAGE_KEY_EXPORT_ALLOWED** can be used for key agreement. If **HuksKeyStorageType** is not passed in, the key can be stored and exported by default, which poses security risks. + ```ts /* * Perform key agreement using an X25519 256-bit TEMP key and return the result in a callback. @@ -965,7 +970,7 @@ struct Index { import huks from '@ohos.security.huks'; /* - * Determine the key alias and encapsulate the key properties. + * Set the key alias and encapsulate the key properties. */ let srcKeyAliasFirst = "AgreeX25519KeyFirstAlias"; let srcKeyAliasSecond = "AgreeX25519KeySecondAlias"; @@ -1002,6 +1007,10 @@ properties[5] = { tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, value: huks.HuksCipherMode.HUKS_MODE_CBC, } +properties[6] = { + tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, + value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, +} let HuksOptions = { properties: properties, inData: new Uint8Array(new Array()) @@ -1010,8 +1019,8 @@ let HuksOptions = { /* Configure parameters for the first key agreement. */ let finishProperties = new Array(); finishProperties[0] = { - tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG, - value: huks.HuksKeyStorageType.HUKS_STORAGE_TEMP, + tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, + value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, } finishProperties[1] = { tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS, @@ -1322,6 +1331,9 @@ async function testAgree() { ``` ### Key Derivation + +You are advised to pass in [HuksKeyStorageType](../reference/apis/js-apis-huks.md#hukskeystoragetype) for key derivation. From API version 10, only **HUKS_STORAGE_ONLY_USED_IN_HUKS** or **HUKS_STORAGE_KEY_EXPORT_ALLOWED** can be used for key derivation. If **HuksKeyStorageType** is not passed in, the key can be stored and exported by default, which poses security risks. + ```ts /* * The following uses an HKDF256 key and promise-based APIs as an example. @@ -1329,7 +1341,7 @@ async function testAgree() { import huks from '@ohos.security.huks'; /* - * Determine the key alias and encapsulate the key properties. + * Set the key alias and encapsulate the key properties. */ let srcKeyAlias = "hkdf_Key"; let deriveHkdfInData = "deriveHkdfTestIndata"; @@ -1355,6 +1367,10 @@ properties[3] = { tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128, } +properties[4] = { + tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, + value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, +} let huksOptions = { properties: properties, inData: new Uint8Array(new Array()) @@ -1386,8 +1402,8 @@ let initOptions = { /* Configure the parameter set used for finish(). */ let finishProperties = new Array(); finishProperties[0] = { - tag: huks.HuksTag.HUKS_TAG_KEY_STORAGE_FLAG, - value: huks.HuksKeyStorageType.HUKS_STORAGE_PERSISTENT, + tag: huks.HuksTag.HUKS_TAG_DERIVED_AGREED_KEY_STORAGE_FLAG, + value: huks.HuksKeyStorageType.HUKS_STORAGE_ONLY_USED_IN_HUKS, } finishProperties[1] = { tag: huks.HuksTag.HUKS_TAG_IS_KEY_ALIAS, @@ -1646,12 +1662,13 @@ Services can access only their own keys, that is, the keys generated or imported In addition, the HUKS supports user identity authentication for security-sensitive services. Users can use the service keys only after the authentication (PIN or biometric authentication) is successful. The HUKS also restricts the key usage. For example, the AES keys can only be used for encryption and decryption, and the RSA keys can only be used for signing and signature verification. -**User Identity Authentication** +### User Identity Authentication -When generating or importing a key, you can enable user identity authentication for the key use. You can specify a subset of credentials (lock screen password, fingerprint, and face) for user identity authentication. After a key is generated or imported, unauthorized key access can be prevented even if the application process is attacked. Key access control applies to security-sensitive scenarios, such as password-free login, password-free payment, and automatic password filling. +During the key generation or import process, user identity authentication can be enabled to allow the use of the key only after the authentication is successful. You can specify a subset of credentials (lock screen password, fingerprint, and face) for user identity authentication. After a key is generated or imported, unauthorized key access can be prevented even if the application process is attacked. Key access control applies to security-sensitive scenarios, such as password-free login, password-free payment, and automatic password filling. In addition to user identity authentication, the HUKS provides the following modes for automatically invalidating a key: -- Invalidate the key when the screen lock password is cleared.
This mode takes effect only when a screen lock password has been set. If the screen lock password is cleared, the key becomes invalid permanently. The key will not be invalidated if the screen lock password is modified. This mode applies to user-related data protection and access based on screen lock passwords. + +- Invalidate the key when the screen lock password is cleared.
This mode takes effect only when a screen lock password has been set. If the screen lock password is cleared, the key becomes invalid permanently. The key will not be invalidated if the screen lock password is modified. This mode applies to user-related data protection or access based on screen lock passwords. - Invalidate the key when new biometric enrollments are added.
This mode takes effect only when at least one biometric feature (such as fingerprint) has been enrolled. The key becomes invalid permanently once a new biometric feature is enrolled. The key will not be invalidated if the biometric feature is deleted. This mode applies to scenarios, such as password-free login or payment. To ensure the validity of the user authentication result, the HUKS supports challenge verification. Before user identity authentication, obtain the challenge (in [HuksSessionHandle](../reference/apis/js-apis-huks.md#hukssessionhandle9) returned by [huks.initSession()](../reference/apis/js-apis-huks.md#huksinitsession9)) from the HUKS and pass in the challenge in [userIAM_userAuth.getAuthInstance](../reference/apis/js-apis-useriam-userauth.md#authinstance9). The challenge of the authentication token is then verified during key operations. @@ -1668,33 +1685,33 @@ When a key is generated or imported, [HuksUserAuthType](../reference/apis/js-api **Table 3** User authentication types -| Name | Value | Description | -| ------------------------------- |---|------------------------ | -| HUKS_USER_AUTH_TYPE_FINGERPRINT |0x0001 | Fingerprint authentication.
Fingerprint authentication, facial authentication, and PIN authentication can be enabled at the same time. | -| HUKS_USER_AUTH_TYPE_FACE |0x0002 | Facial authentication.
Fingerprint authentication, facial authentication, and PIN authentication can be enabled at the same time.| -| HUKS_USER_AUTH_TYPE_PIN |0x0004 | PIN authentication.
Fingerprint authentication, facial authentication, and PIN authentication can be enabled at the same time.| +| Name | Value | Description | +| ------------------------------- | ------ | ------------------------------------------------------------ | +| HUKS_USER_AUTH_TYPE_FINGERPRINT | 0x0001 | Fingerprint authentication, which can be enabled with facial authentication and PIN authentication at the same time. | +| HUKS_USER_AUTH_TYPE_FACE | 0x0002 | Facial authentication, whch can be enabled with fingerprint authentication and PIN authentication at the same time. | +| HUKS_USER_AUTH_TYPE_PIN | 0x0004 | PIN authentication, which can be enabled with fingerprint authentication and facial authenticationat the same time. | **Table 4** Secure access types -| Name | Value | Description | -| --------------------------------------- | ---- | ------------------------------------------------ | -| HUKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD | 1 | Invalidate the key after the screen lock password is cleared. | -| HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL | 2 | Invalidate the key after a biometric enrollment is added. The user authentication types must include the biometric authentication.| + +| Name | Value | Description | +| --------------------------------------- | ----- | ------------------------------------------------------------ | +| HUKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD | 1 | Invalidate the key after the screen lock password is cleared. | +| HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL | 2 | Invalidate the key after a biometric enrollment is added. The user authentication types must include the biometric authentication. | **Table 5** Challenge types -| Name | Value | Description | -| ------------------------------- | ---- | ------------------------------ | -| HUKS_CHALLENGE_TYPE_NORMAL | 0 | Normal challenge, which requires an independent user authentication for each use of the key.| -| HUKS_CHALLENGE_TYPE_CUSTOM | 1 | Custom challenge, which supports only one user authentication for multiple keys.| -| HUKS_CHALLENGE_TYPE_NONE | 2 | No challenge is required during user authentication.| + +| Name | Value | Description | +| -------------------------- | ----- | ------------------------------------------------------------ | +| HUKS_CHALLENGE_TYPE_NORMAL | 0 | Normal challenge, which requires an independent user authentication for each use of the key. | +| HUKS_CHALLENGE_TYPE_CUSTOM | 1 | Custom challenge, which supports only one user authentication for multiple keys. | +| HUKS_CHALLENGE_TYPE_NONE | 2 | No challenge is required during user authentication. | > **NOTICE** > > - The three challenge types are mutually exclusive. > - If the challenge type is **HUKS_CHALLENGE_TYPE_NONE**, no challenge is required. However, the key can be accessed within a specified time period (set by **HUKS_TAG_AUTH_TIMEOUT**) after a successful authentication. The maximum value of **HUKS_TAG_AUTH_TIMEOUT** is 60 seconds. - -To use a key, initialize the key session, and determine whether a challenge is required based on the challenge type specified when the key is generated or imported. - +To use a key, initialize the key session, and determine whether a challenge is required based on the challenge type specified when the key is generated or imported. **Table 6** APIs for using a key @@ -1702,390 +1719,836 @@ To use a key, initialize the key session, and determine whether a challenge is r | -------------------------------------- | ----------------------------| |initSession(keyAlias: string, options: HuksOptions, callback: AsyncCallback\) : void| Initializes the key session and obtains the challenge.| |updateSession(handle: number, options: HuksOptions, token: Uint8Array, callback: AsyncCallback\) : void| Operates data by segment and passes the authentication token.| -|finishSession(handle: number, options: HuksOptions, token: Uint8Array, callback: AsyncCallback\) : void| Finalizes the key session operation. | +|finishSession(handle: number, options: HuksOptions, token: Uint8Array, callback: AsyncCallback\) : void| Completes the key session operation.| + +**How to Develop** + +1. Generate a key and specify user authentication properties. + + ```ts + import huks from '@ohos.security.huks'; + + /* + * Set the key alias and encapsulate the key properties. + */ + let keyAlias = 'dh_key_fingerprint_access'; + let properties = new Array(); + properties[0] = { + tag: huks.HuksTag.HUKS_TAG_ALGORITHM, + value: huks.HuksKeyAlg.HUKS_ALG_SM4, + } + properties[1] = { + tag: huks.HuksTag.HUKS_TAG_PURPOSE, + value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, + } + properties[2] = { + tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, + value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, + } + properties[3] = { + tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, + value: huks.HuksCipherMode.HUKS_MODE_CBC, + } + properties[4] = { + tag: huks.HuksTag.HUKS_TAG_PADDING, + value: huks.HuksKeyPadding.HUKS_PADDING_NONE, + } + // Enable fingerprint authentication. + properties[5] = { + tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE, + value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT + } + // Set the key expiration type. Invalidate the key when a new biometric feature (fingerprint) is enrolled. + properties[6] = { + tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE, + value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL + } + // Use the default challenge type. + properties[7] = { + tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE, + value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL + } + let huksOptions = { + properties: properties, + inData: new Uint8Array(new Array()) + } + /* + * Generate a key. + */ + function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) { + return new Promise((resolve, reject) => { + try { + huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } + async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { + console.info(`enter callback generateKeyItem`); + let throwObject = {isThrow: false}; + try { + await generateKeyItem(keyAlias, huksOptions, throwObject) + .then((data) => { + console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); + }) + .catch(error => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } + + async function TestGenKeyForFingerprintAccessControl() { + await publicGenKeyFunc(keyAlias, huksOptions); + } + ``` + +2. Initialize the key session to obtain a challenge, and initiate fingerprint authentication to obtain an authentication token. + + ```ts + import huks from '@ohos.security.huks'; + import userIAM_userAuth from '@ohos.userIAM.userAuth'; + + /* + * Set the key alias and encapsulate the key properties. + */ + let srcKeyAlias = 'sm4_key_fingerprint_access'; + let handle; + let challenge; + let fingerAuthToken; + let authType = userIAM_userAuth.UserAuthType.FINGERPRINT; + let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1; + + /* Configure the key generation parameter set and key encryption parameter set. */ + let properties = new Array(); + properties[0] = { + tag: huks.HuksTag.HUKS_TAG_ALGORITHM, + value: huks.HuksKeyAlg.HUKS_ALG_SM4, + } + properties[1] = { + tag: huks.HuksTag.HUKS_TAG_PURPOSE, + value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, + } + properties[2] = { + tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, + value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, + } + properties[3] = { + tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, + value: huks.HuksCipherMode.HUKS_MODE_CBC, + } + properties[4] = { + tag: huks.HuksTag.HUKS_TAG_PADDING, + value: huks.HuksKeyPadding.HUKS_PADDING_NONE, + } + let huksOptions = { + properties: properties, + inData: new Uint8Array(new Array()) + } + + function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise { + return new Promise((resolve, reject) => { + try { + huks.initSession(keyAlias, huksOptions, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } + + async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { + console.info(`enter callback doInit`); + let throwObject = {isThrow: false}; + try { + await initSession(keyAlias, huksOptions, throwObject) + .then ((data) => { + console.info(`callback: doInit success, data = ${JSON.stringify(data)}`); + handle = data.handle; + challenge = data.challenge; + }) + .catch((error) => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } + + function userIAMAuthFinger(huksChallenge:Uint8Array) { + // Obtain an authentication object. + let auth; + try { + auth = userIAM_userAuth.getAuthInstance(huksChallenge, authType, authTrustLevel); + console.log("get auth instance success"); + } catch (error) { + console.log("get auth instance failed" + error); + } + + // Subscribe to the authentication result. + try { + auth.on("result", { + callback: (result: userIAM_userAuth.AuthResultInfo) => { + /* The authentication is successful, and the authentication token is obtained. */ + fingerAuthToken = result.token; + } + }); + console.log("subscribe authentication event success"); + } catch (error) { + console.log("subscribe authentication event failed " + error); + } + + // Start user authentication. + try { + auth.start(); + console.info("authV9 start auth success"); + } catch (error) { + console.info("authV9 start auth failed, error = " + error); + } + } + + async function testInitAndAuthFinger() { + /* Initialize the key session to obtain a challenge. */ + await publicInitFunc(srcKeyAlias, huksOptions); + /* Invoke userIAM to perform user identity authentication. */ + userIAMAuthFinger(challenge); + } + ``` + +3. Pass in the authentication token to perform data operations. + + ```ts + /* + *The following uses an SM4 128-bit key and callback-based APIs as an example. + */ + import huks from '@ohos.security.huks'; + + /* + *Set the key alias and encapsulate the key properties. + */ + let srcKeyAlias = 'sm4_key_fingerprint_access'; + let IV = '1234567890123456'; + let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; + let handle; + let fingerAuthToken; + let updateResult = new Array(); + let finishOutData; + + /* Configure the key generation parameter set and key encryption parameter set. */ + let propertiesEncrypt = new Array(); + propertiesEncrypt[0] = { + tag: huks.HuksTag.HUKS_TAG_ALGORITHM, + value: huks.HuksKeyAlg.HUKS_ALG_SM4, + } + propertiesEncrypt[1] = { + tag: huks.HuksTag.HUKS_TAG_PURPOSE, + value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, + } + propertiesEncrypt[2] = { + tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, + value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, + } + propertiesEncrypt[3] = { + tag: huks.HuksTag.HUKS_TAG_PADDING, + value: huks.HuksKeyPadding.HUKS_PADDING_NONE, + } + propertiesEncrypt[4] = { + tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, + value: huks.HuksCipherMode.HUKS_MODE_CBC, + } + propertiesEncrypt[5] = { + tag: huks.HuksTag.HUKS_TAG_IV, + value: StringToUint8Array(IV), + } + let encryptOptions = { + properties: propertiesEncrypt, + inData: new Uint8Array(new Array()) + } + + function StringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); + } + + function updateSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise { + return new Promise((resolve, reject) => { + try { + huks.updateSession(handle, huksOptions, token, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } + + async function publicUpdateFunc(handle:number, token:Uint8Array, huksOptions:huks.HuksOptions) { + console.info(`enter callback doUpdate`); + let throwObject = {isThrow: false}; + try { + await updateSession(handle, huksOptions, token, throwObject) + .then ((data) => { + console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); + }) + .catch(error => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } + + function finishSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise { + return new Promise((resolve, reject) => { + try { + huks.finishSession(handle, huksOptions, token, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } + + async function publicFinishFunc(handle:number, token:Uint8Array, huksOptions:huks.HuksOptions) { + console.info(`enter callback doFinish`); + let throwObject = {isThrow: false}; + try { + await finishSession(handle, huksOptions, token, throwObject) + .then ((data) => { + finishOutData = data.outData; + console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); + }) + .catch(error => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } + + async function testSm4Cipher() { + encryptOptions.inData = StringToUint8Array(cipherInData); + /* Pass in the authentication token. */ + await publicUpdateFunc(handle, fingerAuthToken, encryptOptions); + encryptUpdateResult = updateResult; + + encryptOptions.inData = new Uint8Array(new Array()); + /* Pass in the authentication token. */ + await publicFinishFunc(handle, fingerAuthToken, encryptOptions); + if (finishOutData === cipherInData) { + console.info('test finish encrypt err '); + } else { + console.info('test finish encrypt success'); + } + } + ``` + + +### Fine-grained User Identity Authentication + +As an extension of the [Key Access Control](#key-access-control), the fine-grained access control allows secondary user identity authentication (biometric authentication and lock screen password) to be performed for key access in one or more scenarios, such as encryption, decryption, signing, signature verification, key agreement, and key derivation. For example, a service needs to use a HUKS key to encrypt the account password information. In this scenario, identity authentication is not required in encryption but required in decryption. To achieve this purpose, you can use the fine-grained user identity authentication feature provided by the HUKS. **How to Develop** -1. Generate a key and specify user authentication properties. -```ts -import huks from '@ohos.security.huks'; +1. Specify [**HUKS_TAG_KEY_AUTH_PURPOSE**](../reference/apis/js-apis-huks.md#hukstag) for key generation to allow user identity authentication to be performed when a specific algorithm is used. +2. The **HUKS_TAG_KEY_AUTH_PURPOSE** does not need to be specified for the key usage process. The development process is the same as that of the user identity authentication process. -/* - * Determine the key alias and encapsulate the key properties. - */ -let keyAlias = 'dh_key_fingerprint_access'; -let properties = new Array(); -properties[0] = { - tag: huks.HuksTag.HUKS_TAG_ALGORITHM, - value: huks.HuksKeyAlg.HUKS_ALG_SM4, -} -properties[1] = { - tag: huks.HuksTag.HUKS_TAG_PURPOSE, - value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, -} -properties[2] = { - tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, - value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, -} -properties[3] = { - tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, - value: huks.HuksCipherMode.HUKS_MODE_CBC, -} -properties[4] = { - tag: huks.HuksTag.HUKS_TAG_PADDING, - value: huks.HuksKeyPadding.HUKS_PADDING_NONE, -} -// Enable fingerprint authentication. -properties[5] = { - tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE, - value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT -} -// Set the key expiration type. Invalidate the key when a new biometric feature (fingerprint) is enrolled. -properties[6] = { - tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE, - value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL -} -// Use the default challenge type. -properties[7] = { - tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE, - value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL -} -let huksOptions = { - properties: properties, - inData: new Uint8Array(new Array()) -} +**Available APIs** -/* - * Generate a key. - */ -function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) { - return new Promise((resolve, reject) => { - try { - huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { - if (error) { - reject(error); - } else { - resolve(data); - } - }); - } catch (error) { - throwObject.isThrow = true; - throw(error); - } - }); -} +You can use the [**HUKS_TAG_KEY_AUTH_PURPOSE**](../reference/apis/js-apis-huks.md#hukstag) tag to specify the scenario, for which the fine-grained user identity authentication is performed. The value range of this tag is [HuksKeyAlg](../reference/apis/js-apis-huks.md#hukskeyalg). -async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { - console.info(`enter callback generateKeyItem`); - let throwObject = {isThrow: false}; - try { - await generateKeyItem(keyAlias, huksOptions, throwObject) - .then((data) => { - console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); - }) - .catch(error => { - if (throwObject.isThrow) { - throw(error); - } else { - console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); - } - }); - } catch (error) { - console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); - } -} +**Table 7** HUKS_TAG_KEY_AUTH_PURPOSE +| Name | Description | +| -------------------------------------- | ----------------------------| +|HUKS_TAG_KEY_AUTH_PURPOSE| Purpose of the user identity authentication, that is, perform the user identity authentication when a specific algorithm is used.| -async function TestGenKeyForFingerprintAccessControl() { - await publicGenKeyFunc(keyAlias, huksOptions); -} -``` +> **NOTE** +> +> - If [**HuksUserAuthType**](../reference/apis/js-apis-huks.md#huksuserauthtype9) is not specified, no user identity authentication is performed by default. In this case, the setting of **HUKS_TAG_KEY_AUTH_PURPOSE** is invalid by default. If **HuksUserAuthType** is specified and **HUKS_TAG_KEY_AUTH_PURPOSE** is not specified, user identity authentication will still be performed by default before the key is used with the algorithm that is specified in the key generation process. +> - If the AES or SM4 symmetric algorithm is used for encryption and decryption, only the CBC mode supports fine-grained user identity authentication. +**How to Develop** -2. Initialize the key session to obtain a challenge, and initiate fingerprint authentication to obtain an authentication token. -```ts -import huks from '@ohos.security.huks'; -import userIAM_userAuth from '@ohos.userIAM.userAuth'; +Scenario: When generating keys for encryption and decryption, enable user identity authentication only for decryption. Enable user identity authentication for decryption but not for encryption. -/* - * Determine the key alias and encapsulate the key properties. - */ -let srcKeyAlias = 'sm4_key_fingerprint_access'; -let handle; -let challenge; -let fingerAuthToken; -let authType = userIAM_userAuth.UserAuthType.FINGERPRINT; -let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1; +1. Generate a key, set fingerprint authentication for key access control and related properties, and set **HUKS_TAG_KEY_AUTH_PURPOSE**. -/* Configure the key generation parameter set and key encryption parameter set. */ -let properties = new Array(); -properties[0] = { - tag: huks.HuksTag.HUKS_TAG_ALGORITHM, - value: huks.HuksKeyAlg.HUKS_ALG_SM4, -} -properties[1] = { - tag: huks.HuksTag.HUKS_TAG_PURPOSE, - value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, -} -properties[2] = { - tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, - value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, -} -properties[3] = { - tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, - value: huks.HuksCipherMode.HUKS_MODE_CBC, -} -properties[4] = { - tag: huks.HuksTag.HUKS_TAG_PADDING, - value: huks.HuksKeyPadding.HUKS_PADDING_NONE, -} -let huksOptions = { - properties: properties, - inData: new Uint8Array(new Array()) -} + ```ts + import huks from '@ohos.security.huks'; -function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise { - return new Promise((resolve, reject) => { - try { - huks.initSession(keyAlias, huksOptions, function (error, data) { - if (error) { - reject(error); - } else { - resolve(data); - } - }); - } catch (error) { - throwObject.isThrow = true; - throw(error); - } - }); -} + /* + * Set the key alias and encapsulate the key properties. + */ + let keyAlias = 'dh_key_fingerprint_access'; + let properties = new Array(); + properties[0] = { + tag: huks.HuksTag.HUKS_TAG_ALGORITHM, + value: huks.HuksKeyAlg.HUKS_ALG_SM4, + } + properties[1] = { + tag: huks.HuksTag.HUKS_TAG_PURPOSE, + value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT | huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, + } + properties[2] = { + tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, + value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, + } + properties[3] = { + tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, + value: huks.HuksCipherMode.HUKS_MODE_CBC, + } + properties[4] = { + tag: huks.HuksTag.HUKS_TAG_PADDING, + value: huks.HuksKeyPadding.HUKS_PADDING_NONE, + } + // Enable fingerprint authentication. + properties[5] = { + tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE, + value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT + } + // Set the key expiration type. Invalidate the key when a new biometric feature (fingerprint) is enrolled. + properties[6] = { + tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE, + value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL + } + // Use the default challenge type. + properties[7] = { + tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE, + value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL + } + // Perform user identity authentication when the key is used for decryption. + properties[8] = { + tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_PURPOSE, + value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT + } + let huksOptions = { + properties: properties, + inData: new Uint8Array(new Array()) + } -async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { - console.info(`enter callback doInit`); - let throwObject = {isThrow: false}; - try { - await initSession(keyAlias, huksOptions, throwObject) - .then ((data) => { - console.info(`callback: doInit success, data = ${JSON.stringify(data)}`); - handle = data.handle; - challenge = data.challenge; - }) - .catch((error) => { - if (throwObject.isThrow) { - throw(error); - } else { - console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`); - } - }); - } catch (error) { - console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); - } -} + /* + * Generate a key. + */ + async function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) { + return new Promise((resolve, reject) => { + try { + huks.generateKeyItem(keyAlias, huksOptions, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } -function userIAMAuthFinger(huksChallenge:Uint8Array) { - // Obtain an authentication object. - let auth; - try { - auth = userIAM_userAuth.getAuthInstance(huksChallenge, authType, authTrustLevel); - console.log("get auth instance success"); - } catch (error) { - console.log("get auth instance failed" + error); - } + async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) { + console.info(`enter callback generateKeyItem`); + let throwObject = {isThrow: false}; + try { + await generateKeyItem(keyAlias, huksOptions, throwObject) + .then((data) => { + console.info(`callback: generateKeyItem success, data = ${JSON.stringify(data)}`); + }) + .catch(error => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: generateKeyItem failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: generateKeyItem input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } - // Subscribe to the authentication result. - try { - auth.on("result", { - callback: (result: userIAM_userAuth.AuthResultInfo) => { - /* The authentication is successful, and the authentication token is obtained. */ - fingerAuthToken = result.token; - } - }); - console.log("subscribe authentication event success"); - } catch (error) { - console.log("subscribe authentication event failed " + error); - } + async function TestGenKeyForFingerprintAccessControl() { + await publicGenKeyFunc(keyAlias, huksOptions); + } + ``` + +2. Disable user identity authentication when the key is used for encryption. + + ```ts + import huks from '@ohos.security.huks'; + + /* + * Set the key alias and encapsulate the key properties. + */ + let srcKeyAlias = 'sm4_key_fingerprint_access'; + let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; // Plaintext + let IV = '1234567890123456'; + let handle; + let cipherText; // Ciphertext after encryption. + + function StringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); + } - // Start user authentication. - try { - auth.start(); - console.info("authV9 start auth success"); - } catch (error) { - console.info("authV9 start auth failed, error = " + error); - } -} + /* Configure the key generation parameter set and key encryption parameter set. */ + let propertiesEncrypt = new Array(); + propertiesEncrypt[0] = { + tag: huks.HuksTag.HUKS_TAG_ALGORITHM, + value: huks.HuksKeyAlg.HUKS_ALG_SM4, + } + propertiesEncrypt[1] = { + tag: huks.HuksTag.HUKS_TAG_PURPOSE, + value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, + } + propertiesEncrypt[2] = { + tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, + value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, + } + propertiesEncrypt[3] = { + tag: huks.HuksTag.HUKS_TAG_PADDING, + value: huks.HuksKeyPadding.HUKS_PADDING_NONE, + } + propertiesEncrypt[4] = { + tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, + value: huks.HuksCipherMode.HUKS_MODE_CBC, + } + propertiesEncrypt[5] = { + tag: huks.HuksTag.HUKS_TAG_IV, + value: StringToUint8Array(IV), + } + let encryptOptions = { + properties: propertiesEncrypt, + inData: new Uint8Array(new Array()) + } -async function testInitAndAuthFinger() { - /* Initialize the key session to obtain a challenge. */ - await publicInitFunc(srcKeyAlias, huksOptions); - /* Invoke userIAM to perform user identity authentication. */ - userIAMAuthFinger(challenge); -} -``` + function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise { + return new Promise((resolve, reject) => { + try { + huks.initSession(keyAlias, huksOptions, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } -3. Pass in the authentication token to perform data operations. -```ts -/* - * The following uses an SM4 128-bit key and callback-based APIs as an example. - */ -import huks from '@ohos.security.huks'; + async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { + console.info(`enter callback doInit`); + let throwObject = {isThrow: false}; + try { + await initSession(keyAlias, huksOptions, throwObject) + .then ((data) => { + console.info(`callback: doInit success, data = ${JSON.stringify(data)}`); + handle = data.handle; + }) + .catch((error) => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } -/* - * Determine the key alias and encapsulate the key properties. - */ -let srcKeyAlias = 'sm4_key_fingerprint_access'; -let IV = '1234567890123456'; -let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; -let handle; -let fingerAuthToken; -let updateResult = new Array(); -let finishOutData; + function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise { + return new Promise((resolve, reject) => { + try { + huks.finishSession(handle, huksOptions, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } -/* Configure the key generation parameter set and key encryption parameter set. */ -let propertiesEncrypt = new Array(); -propertiesEncrypt[0] = { - tag: huks.HuksTag.HUKS_TAG_ALGORITHM, - value: huks.HuksKeyAlg.HUKS_ALG_SM4, -} -propertiesEncrypt[1] = { - tag: huks.HuksTag.HUKS_TAG_PURPOSE, - value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT, -} -propertiesEncrypt[2] = { - tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, - value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, -} -propertiesEncrypt[3] = { - tag: huks.HuksTag.HUKS_TAG_PADDING, - value: huks.HuksKeyPadding.HUKS_PADDING_NONE, -} -propertiesEncrypt[4] = { - tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, - value: huks.HuksCipherMode.HUKS_MODE_CBC, -} -propertiesEncrypt[5] = { - tag: huks.HuksTag.HUKS_TAG_IV, - value: StringToUint8Array(IV), -} -let encryptOptions = { - properties: propertiesEncrypt, - inData: new Uint8Array(new Array()) -} + async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) { + console.info(`enter callback doFinish`); + let throwObject = {isThrow: false}; + try { + await finishSession(handle, huksOptions, throwObject) + .then ((data) => { + cipherText = data.outData; + console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); + }) + .catch(error => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } -function StringToUint8Array(str) { - let arr = []; - for (let i = 0, j = str.length; i < j; ++i) { - arr.push(str.charCodeAt(i)); - } - return new Uint8Array(arr); -} + async function testSm4Cipher() { + /* Initialize the key session to obtain a challenge. */ + await publicInitFunc(srcKeyAlias, encryptOptions); -function updateSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise { - return new Promise((resolve, reject) => { - try { - huks.updateSession(handle, huksOptions, token, function (error, data) { - if (error) { - reject(error); - } else { - resolve(data); - } - }); - } catch (error) { - throwObject.isThrow = true; - throw(error); - } - }); -} + /** Encryption */ + encryptOptions.inData = StringToUint8Array(cipherInData); + await publicFinishFunc(handle, encryptOptions); + } + ``` + +3. Enable user identity authentication when the key is used for decryption. + + ```ts + import huks from '@ohos.security.huks'; + import userIAM_userAuth from '@ohos.userIAM.userAuth'; + + /* + * Set the key alias and encapsulate the key properties. + */ + let srcKeyAlias = 'sm4_key_fingerprint_access'; + let cipherText = 'r56ywtTJUQC6JFJ2VV2kZw=='; // Ciphertext obtained, which may vary in actual situation. + let IV = '1234567890123456'; + let handle; + let finishOutData; // Plaintext after decryption. + let fingerAuthToken; + let authType = userIAM_userAuth.UserAuthType.FINGERPRINT; + let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1; + + function StringToUint8Array(str) { + let arr = []; + for (let i = 0, j = str.length; i < j; ++i) { + arr.push(str.charCodeAt(i)); + } + return new Uint8Array(arr); + } -async function publicUpdateFunc(handle:number, token:Uint8Array, huksOptions:huks.HuksOptions) { - console.info(`enter callback doUpdate`); - let throwObject = {isThrow: false}; - try { - await updateSession(handle, huksOptions, token, throwObject) - .then ((data) => { - console.info(`callback: doUpdate success, data = ${JSON.stringify(data)}`); - }) - .catch(error => { - if (throwObject.isThrow) { - throw(error); - } else { - console.error(`callback: doUpdate failed, code: ${error.code}, msg: ${error.message}`); - } - }); - } catch (error) { - console.error(`callback: doUpdate input arg invalid, code: ${error.code}, msg: ${error.message}`); - } -} + /* Configure the key generation parameter set and key encryption parameter set. */ + let propertiesDecrypt = new Array(); + propertiesDecrypt[0] = { + tag: huks.HuksTag.HUKS_TAG_ALGORITHM, + value: huks.HuksKeyAlg.HUKS_ALG_SM4, + } + propertiesDecrypt[1] = { + tag: huks.HuksTag.HUKS_TAG_PURPOSE, + value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT, + } + propertiesDecrypt[2] = { + tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, + value: huks.HuksKeySize.HUKS_SM4_KEY_SIZE_128, + } + propertiesDecrypt[3] = { + tag: huks.HuksTag.HUKS_TAG_PADDING, + value: huks.HuksKeyPadding.HUKS_PADDING_NONE, + } + propertiesDecrypt[4] = { + tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE, + value: huks.HuksCipherMode.HUKS_MODE_CBC, + } + propertiesDecrypt[5] = { + tag: huks.HuksTag.HUKS_TAG_IV, + value: StringToUint8Array(IV), + } + let decryptOptions = { + properties: propertiesDecrypt, + inData: new Uint8Array(new Array()) + } -function finishSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise { - return new Promise((resolve, reject) => { - try { - huks.finishSession(handle, huksOptions, token, function (error, data) { - if (error) { - reject(error); - } else { - resolve(data); - } - }); - } catch (error) { - throwObject.isThrow = true; - throw(error); - } - }); -} + function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise { + return new Promise((resolve, reject) => { + try { + huks.initSession(keyAlias, huksOptions, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } -async function publicFinishFunc(handle:number, token:Uint8Array, huksOptions:huks.HuksOptions) { - console.info(`enter callback doFinish`); - let throwObject = {isThrow: false}; - try { - await finishSession(handle, huksOptions, token, throwObject) - .then ((data) => { - finishOutData = data.outData; - console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); - }) - .catch(error => { - if (throwObject.isThrow) { - throw(error); - } else { - console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); - } - }); - } catch (error) { - console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); - } -} + async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) { + console.info(`enter callback doInit`); + let throwObject = {isThrow: false}; + try { + await initSession(keyAlias, huksOptions, throwObject) + .then ((data) => { + console.info(`callback: doInit success, data = ${JSON.stringify(data)}`); + handle = data.handle; + challenge = data.challenge; + }) + .catch((error) => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: doInit failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: doInit input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } -async function testSm4Cipher() { - encryptOptions.inData = StringToUint8Array(cipherInData); - /* Pass in the authentication token. */ - await publicUpdateFunc(handle, fingerAuthToken, encryptOptions); - encryptUpdateResult = updateResult; + function userIAMAuthFinger(huksChallenge:Uint8Array) { + // Obtain an authentication object. + let auth; + try { + auth = userIAM_userAuth.getAuthInstance(huksChallenge, authType, authTrustLevel); + console.log("get auth instance success"); + } catch (error) { + console.log("get auth instance failed" + error); + } + + // Subscribe to the authentication result. + try { + auth.on("result", { + callback: (result: userIAM_userAuth.AuthResultInfo) => { + /* The authentication is successful, and the authentication token is obtained. */ + fingerAuthToken = result.token; + } + }); + console.log("subscribe authentication event success"); + } catch (error) { + console.log("subscribe authentication event failed " + error); + } + + // Start user authentication. + try { + auth.start(); + console.info("authV9 start auth success"); + } catch (error) { + console.info("authV9 start auth failed, error = " + error); + } + } - encryptOptions.inData = new Uint8Array(new Array()); - /* Pass in the authentication token. */ - await publicFinishFunc(handle, fingerAuthToken, encryptOptions); - if (finishOutData === cipherInData) { - console.info('test finish encrypt err '); - } else { - console.info('test finish encrypt success'); - } -} -``` + function finishSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise { + return new Promise((resolve, reject) => { + try { + huks.finishSession(handle, huksOptions, token, function (error, data) { + if (error) { + reject(error); + } else { + resolve(data); + } + }); + } catch (error) { + throwObject.isThrow = true; + throw(error); + } + }); + } + + async function publicFinishFunc(handle:number, token:Uint8Array, huksOptions:huks.HuksOptions) { + console.info(`enter callback doFinish`); + let throwObject = {isThrow: false}; + try { + await finishSession(handle, huksOptions, token, throwObject) + .then ((data) => { + finishOutData = data.outData; + console.info(`callback: doFinish success, data = ${JSON.stringify(data)}`); + }) + .catch(error => { + if (throwObject.isThrow) { + throw(error); + } else { + console.error(`callback: doFinish failed, code: ${error.code}, msg: ${error.message}`); + } + }); + } catch (error) { + console.error(`callback: doFinish input arg invalid, code: ${error.code}, msg: ${error.message}`); + } + } + + async function testSm4Cipher() { + /* Initialize the key session to obtain a challenge. */ + await publicInitFunc(srcKeyAlias, decryptOptions); + + /* Invoke userIAM to perform user identity authentication. */ + userIAMAuthFinger(challenge); + + /* Perform decryption after the authentication is successful. The **authToken** value obtained by Auth needs to be passed in. */ + decryptOptions.inData = StringToUint8Array(cipherText); + await publicFinishFunc(handle, fingerAuthToken, decryptOptions); + } + ``` ## Key Attestation The HUKS provides attestation for the public keys of asymmetric key pairs. The HUKS can issue a certificate for the public key of an asymmetric key pair stored in the HUKS using the public key infrastructure (PKI) certificate chain technology. The certificate can prove the validity of the public key. The service can use the root CA certificate provided by the OpenHarmony to verify the key certificate issued by the HUKS level by level to ensure that the public key and private key in the certificate are from a trusted hardware device and stored in the HUKS. **How to Develop** + 1. Pass in the key alias and the property tag of the key to be attested. 2. Call a HUKS API to generate an X.509 certificate chain, which consists of the root CA certificate, device CA certificate, device certificate, and key certificate in sequence, for the application. 3. Send the certificate chain to a trusted server. The server parses and verifies the validity of the certificate chain and whether a single certificate is revoked. **Available APIs** -**Table 7** API for key attestation - +**Table 8** API for key attestation | API | Description | | -------------------------------------- | ----------------------------| |attestKeyItem(keyAlias: string, options: HuksOptions, callback: AsyncCallback\) : void| Attests a key.| @@ -2099,7 +2562,7 @@ The HUKS provides attestation for the public keys of asymmetric key pairs. The H import huks from '@ohos.security.huks'; /* - * Determine the key alias and encapsulate the key properties. + * Set the key alias and encapsulate the key properties. */ let keyAliasString = "key attest"; let aliasString = keyAliasString; @@ -2268,4 +2731,4 @@ async function AttestKeyTest() { ### Property 'finishSession' does not exist on type 'typeof huks'. Did you mean 'finish'? -**finishSession()** is supported from API version 9. Update the SDK version or use the latest **security.huks.d.ts** file. \ No newline at end of file + **finishSession()** is supported from API version 9. Update the SDK version or use the latest **security.huks.d.ts** file. diff --git a/en/release-notes/changelogs/OpenHarmony_4.0.7.1/changelog-huks.md b/en/release-notes/changelogs/OpenHarmony_4.0.7.1/changelog-huks.md new file mode 100644 index 0000000000000000000000000000000000000000..7399cead068359b4b99337704f1dc42f7e77172a --- /dev/null +++ b/en/release-notes/changelogs/OpenHarmony_4.0.7.1/changelog-huks.md @@ -0,0 +1,98 @@ +# HUKS Changelog + +## cl.huks.1 HUKS Supports RsaPssSaltLengthType + +Before the change, the HUKS uses **RSA_PSS_SALT_LEN_MAX** for signing or signature verification by default. + +After the change, the type defined by **HuksRsaPssSaltLenType** is passed in for signature or signature verification. If **HuksRsaPssSaltLenType** is not passed in, **RSA_PSS_SALT_LEN_MAX** is used by default. + +**Change Impact** + +Behaviors of released JavaScript APIs have been changed. + +**Key API/Component Changes** + +Released JavaScript APIs remain unchanged, but the parameter set passed to the APIs are changed. + +**Adaptation Guide** + +The following uses RSA signing as an example. + +```js +import huks from '@ohos.security.huks'; + +let keyAlias = 'rsa_Key'; +let inData = new Uint8Array( + 0x4B, 0x1E, 0x22, 0x64, 0xA9, 0x89, 0x60, 0x1D, 0xEC, 0x78, 0xC0, 0x5D, 0xBE, 0x46, 0xAD, 0xCF, + 0x1C, 0x35, 0x16, 0x11, 0x34, 0x01, 0x4E, 0x9B, 0x7C, 0x00, 0x66, 0x0E, 0xCA, 0x09, 0xC0, 0xF3, +); +/* Parameters for signing */ +let signProperties = new Array(); +signProperties[0] = { + tag: huks.HuksTag.HUKS_TAG_ALGORITHM, + value: huks.HuksKeyAlg.HUKS_ALG_RSA, +} +signProperties[1] = { + tag: huks.HuksTag.HUKS_TAG_PURPOSE, + value: + huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN +} +signProperties[2] = { + tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, + value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048, +} +signProperties[3] = { + tag: huks.HuksTag.HUKS_TAG_PADDING, + value: huks.HuksKeyPadding.HUKS_PADDING_PSS, +} +signProperties[4] = { + tag: huks.HuksTag.HUKS_TAG_DIGEST, + value: huks.HuksKeyDigest.HUKS_DIGEST_SHA1, +} +signProperties[5] = { + tag: huks.HuksTag.HUKS_TAG_RSA_PSS_SALT_LEN_TYPE, + value: huks.HuksRsaPssSaltLenType.HUKS_RSA_PSS_SALT_LEN_MAX, +} +let signOptions = { + properties: signProperties, + inData: inData +} + +huks.initSession(keyAlias, signOptions); +``` + +For more information, see [HUKS Development](../../../application-dev/security/huks-guidelines.md) and [HUKS](../../../application-dev/reference/apis/js-apis-huks.md). + +## cl.huks.2 Resolved the Issues in Storage or Export of Derived or Agreed Keys + +Before the change, the HUKS supports storage and export of derived keys and agreed keys, which poses security risks. + +After the change, the application needs to pass in **HuksKeyStorageType** for key derivation or key agreement. Only storage or export is allowed at a time. If this parameter is not passed in, both storage and export are supported by default, which poses security risks and is not recommended. + +**Change Impact** + +Behaviors of released JavaScript APIs have been changed. + +**Key API/Component Changes** + +Released JavaScript APIs remain unchanged, but the parameter set passed to the APIs are changed. + +**Adaptation Guide** + +For more information, see [HUKS Development](../../../application-dev/security/huks-guidelines.md) and [HUKS](../../../application-dev/reference/apis/js-apis-huks.md). + +## cl.huks.3 Adding Tags for Fine-grained User Identity Access Control + +Added **HUKS_TAG_KEY_AUTH_PURPOSE** to **HuksTag** for fine-grained user identity access control. This tag specifies the user identity authentication used for specific algorithm. + +**Change Impact** + +The new HuksTag does not affect existing APIs. + +**Key API/Component Changes** + +**HuksTag** is added with **HUKS_TAG_KEY_AUTH_PURPOSE** to support fine-grained user identity access control. + +**Adaptation Guide** + +For more information, see [Fine-grained User Identity Authentication](../../../application-dev/security/huks-guidelines.md#fine-grained-user-identity-authentication) and [HuksTag](../../../application-dev/reference/apis/js-apis-huks.md#hukstag).