提交 bf90fb09 编写于 作者: G ge-yafang

update docs

Signed-off-by: Nge-yafang <geyafang@huawei.com>
......@@ -737,7 +737,7 @@ class EntryAbility extends UIAbility {
removePreferencesFromCacheSync(context: Context, name: string): void
Synchronously removes a **Preferences** instance from the cache.
Removes a **Preferences** instance from the cache. This API returns the result synchronously.
After an application calls [getPreferences](#data_preferencesgetpreferences) for the first time to obtain a **Preferences** instance, the obtained **Preferences** instance is cached. When the application calls [getPreferences](#data_preferencesgetpreferences) again, the **Preferences** instance will be read from the cache instead of from the persistent file. After this API is called to remove the instance from the cache, calling **getPreferences** again will read data from the persistent file and create a new **Preferences** instance.
......@@ -1021,7 +1021,7 @@ try {
getSync(key: string, defValue: ValueType): ValueType
Synchronously obtains the value corresponding to the specified key from the cached **Preferences** instance. If the value is null or is not of the default value type, **defValue** is returned.
Obtains the value corresponding to the specified key from the cached **Preferences** instance. This API returns the result synchronously. If the value is null or is not of the default value type, **defValue** is returned.
**System capability**: SystemCapability.DistributedDataManager.Preferences.Core
......@@ -1117,7 +1117,7 @@ try {
getAllSync(): Object
Obtains all KV pairs from the cached **Preferences** instance synchronously.
Obtains all KV pairs from the cached **Preferences** instance. This API returns the result synchronously.
**System capability**: SystemCapability.DistributedDataManager.Preferences.Core
......@@ -1214,7 +1214,7 @@ try {
putSync(key: string, value: ValueType): void
Synchronously writes data to the cached **Preferences** instance. You can use [flush](#flush) to persist the **Preferences** instance.
Writes data to the cached **Preferences** instance. This API returns the result synchronously. You can use [flush](#flush) to persist the **Preferences** instance.
**System capability**: SystemCapability.DistributedDataManager.Preferences.Core
......@@ -1316,7 +1316,7 @@ try {
hasSync(key: string): boolean
Synchronously checks whether the cached **Preferences** instance contains the KV pair of the given key.
Checks whether the cached **Preferences** instance contains the KV pair of the given key. This API returns the result synchronously.
**System capability**: SystemCapability.DistributedDataManager.Preferences.Core
......@@ -1420,7 +1420,7 @@ try {
deleteSync(key: string): void
Synchronously deletes a KV pair from the cached **Preferences** instance based on the specified key. You can use [flush](#flush) to persist the **Preferences** instance.
Deletes a KV pair from the cached **Preferences** instance based on the specified key. This API returns the result synchronously. You can use [flush](#flush) to persist the **Preferences** instance.
**System capability**: SystemCapability.DistributedDataManager.Preferences.Core
......@@ -1567,7 +1567,7 @@ try {
clearSync(): void
Synchronously clears all data in the cached **Preferences** instance. You can use [flush](#flush) to persist the **Preferences** instance.
Clears all data in the cached **Preferences** instance. This API returns the result synchronously. You can use [flush](#flush) to persist the **Preferences** instance.
**System capability**: SystemCapability.DistributedDataManager.Preferences.Core
......
......@@ -388,7 +388,16 @@ context.startAbility(want, options).then(() => {
## 启动UIAbility的指定页面
一个UIAbility可以对应多个页面,在不同的场景下启动该UIAbility时需要展示不同的页面,例如从一个UIAbility的页面中跳转到另外一个UIAbility时,希望启动目标UIAbility的指定页面。本文主要讲解目标UIAbility首次启动和目标UIAbility非首次启动两种启动指定页面的场景,以及在讲解启动指定页面之前会讲解到在调用方如何指定启动页面。
### 概述
一个UIAbility可以对应多个页面,在不同的场景下启动该UIAbility时需要展示不同的页面,例如从一个UIAbility的页面中跳转到另外一个UIAbility时,希望启动目标UIAbility的指定页面。
UIAbility的启动分为两种情况:UIAbility冷启动和UIAbility热启动。
- UIAbility冷启动:指的是UIAbility实例处于完全关闭状态下被启动,这需要完整地加载和初始化UIAbility实例的代码、资源等。
- UIAbility热启动:指的是UIAbility实例已经启动并在前台运行过,由于某些原因切换到后台,再次启动该UIAbility实例,这种情况下可以快速恢复UIAbility实例的状态。
本文主要讲解[目标UIAbility冷启动](#目标uiability冷启动)[目标UIAbility热启动](#目标uiability热启动)两种启动指定页面的场景,以及在讲解启动指定页面之前会讲解到在调用方如何指定启动页面。
### 调用方UIAbility指定启动页面
......@@ -416,9 +425,9 @@ context.startAbility(want).then(() => {
```
### 目标UIAbility首次启动
### 目标UIAbility启动
目标UIAbility首次启动时,在目标UIAbility的`onWindowStageCreate()`生命周期回调中,解析EntryAbility传递过来的want参数,获取到需要加载的页面信息url,传入`windowStage.loadContent()`方法。
目标UIAbility启动时,在目标UIAbility的`onWindowStageCreate()`生命周期回调中,解析EntryAbility传递过来的want参数,获取到需要加载的页面信息url,传入`windowStage.loadContent()`方法。
```ts
......@@ -448,7 +457,7 @@ export default class FuncAbility extends UIAbility {
}
```
### 目标UIAbility非首次启动
### 目标UIAbility启动
在应用开发中,会遇到目标UIAbility实例之前已经启动过的场景,这时再次启动目标UIAbility时,不会重新走初始化逻辑,只会直接触发`onNewWant()`生命周期方法。为了实现跳转到指定页面,需要在`onNewWant()`中解析要参数进行处理。
......@@ -460,26 +469,12 @@ export default class FuncAbility extends UIAbility {
4. 用户点击联系人张三的短信按钮,会重新启动短信应用的UIAbility实例。
5. 由于短信应用的UIAbility实例已经启动过了,此时会触发该UIAbility的`onNewWant()`回调,而不会再走`onCreate()``onWindowStageCreate()`等初始化逻辑。
```mermaid
sequenceDiagram
Participant U as 用户
Participant S as 短信应用
Participant C as 联系人应用
U->>S: 打开短信应用
S-->>U: 显示短信应用主页
U->>S: 将设备回到桌面界面
S->>S: 短信应用进入后台
U->>C: 打开联系人应用
C-->>U: 显示联系人应用界面
U->>C: 点击联系人张三的短信按钮
C->>S: 构造Want启动短信应用
S-->>U: 显示给张三发短信的页面
```
图1 目标UIAbility热启动
![](figures/uiability-hot-start.png)
开发步骤如下所示。
1. 首次启动短信应用的UIAbility实例时,在`onWindowStageCreate()`生命周期回调中,通过调用[`getUIContext()`](../reference/apis/js-apis-window.md#getuicontext10)接口获取UI上下文实例[`UIContext`](../reference/apis/js-apis-arkui-UIContext.md)对象。
1. 启动短信应用的UIAbility实例时,在`onWindowStageCreate()`生命周期回调中,通过调用[`getUIContext()`](../reference/apis/js-apis-window.md#getuicontext10)接口获取UI上下文实例[`UIContext`](../reference/apis/js-apis-arkui-UIContext.md)对象。
```ts
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
......@@ -499,15 +494,21 @@ S-->>U: 显示给张三发短信的页面
// Main window is created, set main page for this ability
...
let windowClass: window.Window;
windowStage.getMainWindow((err, data) => {
windowStage.loadContent(url, (err, data) => {
if (err.code) {
console.error(`Failed to obtain the main window. Code is ${err.code}, message is ${err.message}`);
return;
}
windowClass = data;
this.uiContext = windowClass.getUIContext();
})
let windowClass: window.Window;
windowStage.getMainWindow((err, data) => {
if (err.code) {
console.error(TAG, `Failed to obtain the main window. Code is ${err.code}, message is ${err.message}`);
return;
}
windowClass = data;
this.uiContext = windowClass.getUIContext();
})
});
}
}
```
......@@ -519,7 +520,7 @@ S-->>U: 显示给张三发短信的页面
funcAbilityWant: Want;
uiContext: UIContext;
onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam) {
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam) {
if (want?.parameters?.router && want.parameters.router === 'funcA') {
let funcAUrl = 'pages/Second';
let router: Router = this.uiContext.getRouter();
......@@ -738,4 +739,4 @@ Call功能主要接口如下表所示。具体的API详见[接口文档](../refe
针对UIAbility组件间交互开发,有以下相关实例可供参考:
- [UIAbility内和UIAbility间页面的跳转(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Ability/StageAbility)
- [UIAbility内页面间的跳转(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Ability/PagesRouter)
\ No newline at end of file
- [UIAbility内页面间的跳转(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/Ability/PagesRouter)
......@@ -58,7 +58,7 @@ save接口会将文件保存在文件管理器,而不是图库。
save返回的uri权限是读写权限,可以根据结果集里面的uri进行文件读写等操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,使用类似一个按钮去触发打开文件。
```ts
let uri:string;
let uris = null;
async photoViewPickerSave() {
try {
const photoSaveOptions = new picker.PhotoSaveOptions(); // 创建文件管理器保存选项实例
......@@ -68,9 +68,8 @@ save接口会将文件保存在文件管理器,而不是图库。
try {
let photoSaveResult = await photoViewPicker.save(photoSaveOptions);
if (photoSaveResult != undefined) {
console.info("[picker] photoViewPickerSave photoSaveResult = " + JSON.stringify(photoSaveResult));
this.uri = photoSaveResult[0];
console.info('photoViewPicker.save to file succeed and uri is:' + photoSaveResult[0]);
uris = photoSaveResult;
console.info('photoViewPicker.save to file succeed and uris are:' + uris);
}
} catch (err) {
console.error(`[picker] Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
......@@ -112,6 +111,7 @@ save接口会将文件保存在文件管理器,而不是图库。
```ts
const documentSaveOptions = new picker.DocumentSaveOptions(); // 创建文件管理器选项实例
documentSaveOptions.newFileNames = ["DocumentViewPicker01.txt"]; // 保存文件名(可选)
documentSaveOptions.fileSuffixChoices = ['.png', '.txt', '.mp4']; // 保存文件类型(可选)
```
3. 创建文档选择器实例。调用[save()](../reference/apis/js-apis-file-picker.md#save-3)接口拉起FilePicker界面进行文件保存。用户选择目标文件夹,用户选择与文件类型相对应的文件夹,即可完成文件保存操作。保存成功后,返回保存文档的uri。
......@@ -119,11 +119,11 @@ save接口会将文件保存在文件管理器,而不是图库。
</br>save返回的uri权限是读写权限,可以根据结果集中uri进行文件读写等操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,使用类似一个按钮去触发打开文件。
```ts
let uri = null;
let uris = null;
const documentViewPicker = new picker.DocumentViewPicker(); // 创建文件选择器实例
documentViewPicker.save(documentSaveOptions).then((documentSaveResult) => {
uri = documentSaveResult[0];
console.info('documentViewPicker.save to file succeed and uri is:' + uri);
uris = documentSaveResult;
console.info('documentViewPicker.save to file succeed and uris are:' + uris);
}).catch((err) => {
console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
})
......
......@@ -38,11 +38,11 @@
</br>select返回的uri权限是只读权限,可以根据结果集中uri进行读取文件数据操作。注意不能在picker的回调里直接使用此uri进行打开文件操作,需要定义一个全局变量保存uri,使用类似一个按钮去触发打开文件。
```ts
let uri = null;
let uris = null;
const photoViewPicker = new picker.PhotoViewPicker();
photoViewPicker.select(photoSelectOptions).then((photoSelectResult) => {
uri = photoSelectResult.photoUris[0];
console.info('photoViewPicker.select to file succeed and uri is:' + uri);
uris = photoSelectResult.photoUris;
console.info('photoViewPicker.select to file succeed and uris are:' + uris);
}).catch((err) => {
console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
......@@ -77,6 +77,9 @@
```ts
const documentSelectOptions = new picker.DocumentSelectOptions();
documentSelectOptions.maxSelectNumber = 5; // 选择文档的最大数目(可选)
documentSelectOptions.defaultFilePathUri = "file://docs/storage/Users/currentUser/test"; // 指定选择的文件或者目录路径(可选)
documentSelectOptions.fileSuffixFilters = ['.png', '.txt', '.mp4']; // 选择文件的后缀类型(可选)
```
3. 创建文档选择器实例。调用[select()](../reference/apis/js-apis-file-picker.md#select-3)接口拉起FilePicker界面进行文件选择。文件选择成功后,返回被选中文档的uri结果集。
......@@ -85,16 +88,12 @@
</br>例如通过[文件管理接口](../reference/apis/js-apis-file-fs.md)根据uri获取部分文件属性信息,比如文件大小、访问时间、修改时间等。如有获取文件名称需求,请暂时使用[startAbilityForResult](../../application-dev/application-models/uiability-intra-device-interaction.md)获取。
> **说明:**
>
> 目前DocumentSelectOptions不支持参数配置,默认可以选择所有类型的用户文件。
```ts
let uri = null;
let uris = null;
const documentViewPicker = new picker.DocumentViewPicker(); // 创建文件选择器实例
documentViewPicker.select(documentSelectOptions).then((documentSelectResult) => {
uri = documentSelectResult[0];
console.info('documentViewPicker.select to file succeed and uri is:' + uri);
uris = documentSelectResult;
console.info('documentViewPicker.select to file succeed and uris are:' + uris);
}).catch((err) => {
console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
......@@ -172,7 +171,7 @@
let uri = null;
const audioViewPicker = new picker.AudioViewPicker();
audioViewPicker.select(audioSelectOptions).then(audioSelectResult => {
uri = audioSelectOptions[0];
uri = audioSelectResult[0];
console.info('audioViewPicker.select to file succeed and uri is:' + uri);
}).catch((err) => {
console.error(`Invoke audioViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
......
......@@ -593,8 +593,13 @@ class EntryAbility extends UIAbility {
| 类型 | 说明 |
| ---------------- | ---------------------------------- |
<<<<<<< HEAD
| number | 主键的类型可以是number。 |
| string | 主键的类型可以是string。 |
=======
| number | 主键的类型可以是number |
| string | 主键的类型可以是string。 |
>>>>>>> 47cb75c33d5460a146af0ead5e8946365240866f
## UTCTime<sup>10+</sup>
......
......@@ -244,7 +244,7 @@ async function example() {
## DocumentViewPicker
文件选择器对象,用来支撑选择和保存非媒体文件等用户场景,比如各种格式文档。在使用前,需要先创建DocumentViewPicker实例。
文件选择器对象,用来支撑选择和保存各种格式文档。在使用前,需要先创建DocumentViewPicker实例。
**系统能力**:SystemCapability.FileManagement.UserFileService
......@@ -699,7 +699,7 @@ async function example() {
枚举,可选择的媒体文件类型。
**系统能力:** 以下各项对应的系统能力均为 SystemCapability.FileManagement.UserFileService
**系统能力:** SystemCapability.FileManagement.UserFileService
| 名称 | 值 | 说明 |
| ----- | ---- | ---- |
......@@ -711,18 +711,18 @@ async function example() {
图库选择选项。
**系统能力:** 以下各项对应的系统能力均为 SystemCapability.FileManagement.UserFileService
**系统能力:** SystemCapability.FileManagement.UserFileService
| 名称 | 类型 | 必填 | 说明 |
| ----------------------- | ------------------- | ---- | -------------------------------- |
| MIMEType? | [PhotoViewMIMETypes](#photoviewmimetypes) | 否 | 可选择的媒体文件类型,若无此参数,则默认为图片和视频类型 |
| maxSelectNumber? | number | 否 | 选择媒体文件数量的最大值(默认值为50,最大值为500) |
| MIMEType | [PhotoViewMIMETypes](#photoviewmimetypes) | 否 | 可选择的媒体文件类型,若无此参数,则默认为图片和视频类型 |
| maxSelectNumber | number | 否 | 选择媒体文件数量的最大值(默认值为50,最大值为500) |
## PhotoSelectResult
返回图库选择后的结果集。
**系统能力:** 以下各项对应的系统能力均为 SystemCapability.FileManagement.UserFileService
**系统能力:** SystemCapability.FileManagement.UserFileService
| 名称 | 类型 | 可读 | 可写 | 说明 |
| ----------------------- | ------------------- | ---- | ---- | ------------------------------ |
......@@ -733,27 +733,35 @@ async function example() {
图片或视频的保存选项。
**系统能力:** 以下各项对应的系统能力均为 SystemCapability.FileManagement.UserFileService
**系统能力:** SystemCapability.FileManagement.UserFileService
| 名称 | 类型 | 必填 | 说明 |
| ----------------------- | ------------------- | ---- | ---------------------------- |
| newFileNames? | Array&lt;string&gt; | 否 | 拉起photoPicker进行保存图片或视频资源的文件名,若无此参数,则默认需要用户自行输入 |
| newFileNames | Array&lt;string&gt; | 否 | 拉起photoPicker进行保存图片或视频资源的文件名,若无此参数,则默认需要用户自行输入 |
## DocumentSelectOptions
文档选择选项,目前不支持参数配置
文档选择选项。
**系统能力:** SystemCapability.FileManagement.UserFileService
| 名称 | 类型 | 必填 | 说明 |
| ----------------------- | ------------------- | ---- | -------------------------------- |
| maxSelectNumber | number | 否 | 选择文件/目录最大个数,上限500,有效值范围1-500 |
| defaultFilePathUri | string | 否 | 指定选择的文件或者目录路径 |
| fileSuffixFilters | Array&lt;string&gt; | 否 | 选择文件的后缀类型 |
## DocumentSaveOptions
文档保存选项。
**系统能力:** 以下各项对应的系统能力均为 SystemCapability.FileManagement.UserFileService
**系统能力:** SystemCapability.FileManagement.UserFileService
| 名称 | 类型 | 必填 | 说明 |
| ----------------------- | ------------------- | ---- | ---------------------------- |
| newFileNames? | Array&lt;string&gt; | 否 | 拉起documentPicker进行保存的文件名,若无此参数,则默认需要用户自行输入 |
| newFileNames | Array&lt;string&gt; | 否 | 拉起documentPicker进行保存的文件名,若无此参数,则默认需要用户自行输入 |
| defaultFilePathUri | string | 否 | 指定保存的文件或者目录路径 |
| fileSuffixChoices | Array&lt;string&gt; | 否 | 保存文件的后缀类型 |
## AudioSelectOptions
......@@ -765,8 +773,8 @@ async function example() {
音频的保存选项。
**系统能力:** 以下各项对应的系统能力均为 SystemCapability.FileManagement.UserFileService
**系统能力:** SystemCapability.FileManagement.UserFileService
| 名称 | 类型 | 必填 | 说明 |
| ----------------------- | ------------------- | ---- | ---------------------------- |
| newFileNames? | Array&lt;string&gt; | 否 | 拉起audioPicker进行保存音频资源的文件名,若无此参数,则默认需要用户自行输入 |
| newFileNames | Array&lt;string&gt; | 否 | 拉起audioPicker进行保存音频资源的文件名,若无此参数,则默认需要用户自行输入 |
......@@ -6,6 +6,7 @@ HUKS所管理的密钥可以由应用导入或者由应用调用HUKS接口生成
> **说明**
>
> 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
> 以下示例代码片段仅适用于JS语言开发。
## 导入模块
......@@ -896,7 +897,7 @@ async function TestExportFunc(alias, options) {
}
}
function exportKey(alias, options) : Promise<huks.HuksReturnResult> {
function exportKey(alias, options) {
return new Promise((resolve, reject) => {
try {
huks.exportKeyItem(alias, options, function (error, data) {
......
......@@ -173,6 +173,7 @@
```ts
import bundleManager from '@ohos.bundle.bundleManager';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { BusinessError } from '@ohos.base';
async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
let atManager = abilityAccessCtrl.createAtManager();
......@@ -184,14 +185,16 @@
let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
tokenId = appInfo.accessTokenId;
} catch (err) {
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
}
// 校验应用是否被授予权限
try {
grantStatus = await atManager.checkAccessToken(tokenId, permission);
} catch (err) {
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
}
......@@ -222,35 +225,34 @@
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { BusinessError } from '@ohos.base';
const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];
export default class EntryAbility extends UIAbility {
// ...
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
let context = this.context;
let atManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).catch((err) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
// ...
}
// ...
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
let context = this.context;
let atManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
// ...
}
}
```
......@@ -259,37 +261,38 @@
```typescript
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';
const permissions: Array<Permissions> = ['ohos.permission.READ_CALENDAR'];
@Entry
@Component
struct Index {
reqPermissionsFromUser(permissions: Array<Permissions>): void {
let context = getContext(this) as common.UIAbilityContext;
let atManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).catch((err) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}
// 页面展示
build() {
// ...
}
reqPermissionsFromUser(permissions: Array<Permissions>): void {
let context = getContext(this) as common.UIAbilityContext;
let atManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
}
// 页面展示
build() {
// ...
}
}
```
......@@ -297,10 +300,59 @@
调用[requestPermissionsFromUser()](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)方法后,应用程序将等待用户授权的结果。如果用户授权,则可以继续访问目标操作。如果用户拒绝授权,则需要提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限。
ArkTS语法不支持直接使用globalThis,需要通过一个单例的map来做中转。开发者需要:
a. 在EntryAbility.ets中导入构建的单例对象GlobalThis。
```ts
import { GlobalThis } from '../utils/globalThis'; // 需要根据globalThis.ets的路径自行适配
```
b. 在onCreate中添加:
```ts
GlobalThis.getInstance().setContext('context', this.context);
```
> **说明:**
>
> 由于在ts中引入ets文件会有告警提示,需要将EntryAbility.ts的文件后缀修改为EntryAbility.ets,并在module.json5中同步修改。
**globalThis.ets示例代码如下:**
```ts
import common from '@ohos.app.ability.common';
// 构造单例对象
export class GlobalThis {
private constructor() {}
private static instance: GlobalThis;
private _uiContexts = new Map<string, common.UIAbilityContext>();
public static getInstance(): GlobalThis {
if (!GlobalThis.instance) {
GlobalThis.instance = new GlobalThis();
}
return GlobalThis.instance;
}
getContext(key: string): common.UIAbilityContext | undefined {
return this._uiContexts.get(key);
}
setContext(key: string, value: common.UIAbilityContext): void {
this._uiContexts.set(key, value);
}
// 其他需要传递的内容依此扩展
}
```
```ts
import { BusinessError } from '@ohos.base';
import Want from '@ohos.app.ability.Want';
import { GlobalThis } from '../utils/globalThis';
import common from '@ohos.app.ability.common';
function openPermissionsInSystemSettings(): void {
let context = getContext(this) as common.UIAbilityContext;
let wantInfo = {
let context: common.UIAbilityContext = GlobalThis.getInstance().getContext('context');
let wantInfo: Want = {
action: 'action.settings.app.info',
parameters: {
settingsParamBundleName: 'com.example.myapplication' // 打开指定应用的详情页面
......@@ -308,7 +360,7 @@
}
context.startAbility(wantInfo).then(() => {
// ...
}).catch((err) => {
}).catch((err: BusinessError) => {
// ...
})
}
......@@ -319,6 +371,7 @@
通过调用[requestPermissionsFromUser()](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7)接口向用户动态申请授权。
```js
import { BusinessError } from '@ohos.base';
import featureAbility from '@ohos.ability.featureAbility';
reqPermissions() {
......@@ -329,7 +382,7 @@ reqPermissions() {
console.log("data:" + JSON.stringify(data));
console.log("data permissions:" + JSON.stringify(data.permissions));
console.log("data result:" + JSON.stringify(data.authResults));
}, (err) => {
}, (err: BusinessError) => {
console.error('Failed to start ability', err.code);
});
}
......
# 通用密钥库开发指导(ArkTS)
> **说明**
>
> 本开发指导需使用API version 9及以上版本SDK,仅适用于JS语言开发。
## 生成新密钥
HUKS提供为业务安全随机生成密钥的能力。通过HUKS生成的密钥,密钥的全生命周期明文不会出安全环境,能保证任何人都无法接触获取到密钥的明文。即使生成密钥的业务自身,后续也只能通过HUKS提供的接口请求执行密钥操作,获取操作结果,但无法接触到密钥自身。
......@@ -19,7 +23,7 @@ HUKS提供为业务安全随机生成密钥的能力。通过HUKS生成的密钥
**代码示例:**
```ts
```js
/*
* 以下以生成DH密钥的Callback操作使用为例
*/
......@@ -107,7 +111,7 @@ async function TestGenKey() {
**代码示例:**
```ts
```js
/*
* 以导入AES256密钥为例
*/
......@@ -167,7 +171,7 @@ try {
**代码示例:**
```ts
```js
import huks from '@ohos.security.huks';
let keyAlias = 'AES256Alias_sample';
......@@ -246,7 +250,7 @@ try {
**代码示例:**
```ts
```js
/*
* 以下以SM2密钥的Callback操作验证为例
*/
......@@ -277,7 +281,7 @@ let inputEccPair = new Uint8Array([
// 坐标z
0xfb, 0x8b, 0x9f, 0x12, 0xa0, 0x83, 0x19, 0xbe, 0x6a, 0x6f, 0x63, 0x2a, 0x7c, 0x86, 0xba, 0xca,
0x64, 0x0b, 0x88, 0x96, 0xe2, 0xfa, 0x77, 0xbc, 0x71, 0xe3, 0x0f, 0x0f, 0x9e, 0x3c, 0xe5, 0xf9
]);
]);
/*
* 封装密钥属性参数集
......@@ -341,7 +345,7 @@ let importOptions = {
};
// 导出加密导入用途的公钥
function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
function exportKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -358,7 +362,7 @@ function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObjec
});
}
async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicExportKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback export`);
let throwObject = {isThrow: false};
try {
......@@ -380,7 +384,7 @@ async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions
}
// 此处用导入密钥来模拟“生成加密导入用途的密钥”
function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function importKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.importKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -397,7 +401,7 @@ function importKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObjec
});
}
async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicImportKeyFunc(keyAlias, huksOptions) {
console.info(`enter promise importKeyItem`);
let throwObject = {isThrow: false};
try {
......@@ -418,7 +422,7 @@ async function publicImportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions
}
// 执行加密导入
async function publicImportWrappedKey(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions) {
async function publicImportWrappedKey(keyAlias, wrappingKeyAlias, huksOptions) {
console.info(`enter callback importWrappedKeyItem`);
var throwObject = {isThrow: false};
try {
......@@ -438,7 +442,7 @@ async function publicImportWrappedKey(keyAlias:string, wrappingKeyAlias:string,
}
}
function importWrappedKeyItem(keyAlias:string, wrappingKeyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.importWrappedKeyItem(keyAlias, wrappingKeyAlias, huksOptions, function (error, data) {
......@@ -456,7 +460,7 @@ function importWrappedKeyItem(keyAlias:string, wrappingKeyAlias:string, huksOpti
}
// 删除加密导入用途的密钥
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function deleteKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -473,7 +477,7 @@ function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObjec
});
}
async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicDeleteKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback deleteKeyItem`);
let throwObject = {isThrow: false};
try {
......@@ -585,7 +589,7 @@ async function ImportWrappedKeyNormalTest() {
**代码示例:**
```ts
```js
import huks from '@ohos.security.huks';
/*
......@@ -635,7 +639,7 @@ HUKS基于密钥会话来操作数据,使用密钥时基于以下流程:
### 加密解密
```ts
```js
/*
* 以下以AES 128密钥的Callback操作使用为例
*/
......@@ -932,7 +936,7 @@ struct Index {
应用在协商密钥时建议传入[HuksKeyStorageType](../reference/apis/js-apis-huks.md#hukskeystoragetype)中定义的类型;从API10开始应用只能选择存储(HUKS_STORAGE_ONLY_USED_IN_HUKS),或者选择导出(HUKS_STORAGE_KEY_EXPORT_ALLOWED),若不传入,则默认同时支持存储和导出,存在安全问题,不推荐业务使用。
```ts
```js
/*
* 以下以X25519 256 TEMP密钥的Callback操作使用为例
*/
......@@ -1047,7 +1051,7 @@ function StringToUint8Array(str) {
return new Uint8Array(arr);
}
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function generateKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -1064,7 +1068,7 @@ function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObj
});
}
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicGenKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback generateKeyItem`);
let throwObject = {isThrow: false};
try {
......@@ -1084,7 +1088,7 @@ async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
}
}
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
function initSession(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.initSession(keyAlias, huksOptions, function (error, data) {
......@@ -1101,7 +1105,7 @@ function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject)
});
}
async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicInitFunc(keyAlias, huksOptions) {
console.info(`enter callback doInit`);
let throwObject = {isThrow: false};
try {
......@@ -1122,7 +1126,7 @@ async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
}
}
function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
function updateSession(handle, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.updateSession(handle, huksOptions, function (error, data) {
......@@ -1139,7 +1143,7 @@ function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject)
});
}
async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
async function publicUpdateFunc(handle, huksOptions) {
console.info(`enter callback doUpdate`);
let throwObject = {isThrow: false};
try {
......@@ -1159,7 +1163,7 @@ async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
}
}
function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
function finishSession(handle, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.finishSession(handle, huksOptions, function (error, data) {
......@@ -1176,7 +1180,7 @@ function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject)
});
}
async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
async function publicFinishFunc(handle, huksOptions) {
console.info(`enter callback doFinish`);
let throwObject = {isThrow: false};
try {
......@@ -1197,7 +1201,7 @@ async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
}
}
function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
function exportKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.exportKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -1214,7 +1218,7 @@ function exportKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObjec
});
}
async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicExportKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback export`);
let throwObject = {isThrow: false};
try {
......@@ -1235,7 +1239,7 @@ async function publicExportKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions
}
}
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function deleteKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -1252,7 +1256,7 @@ function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObjec
});
}
async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicDeleteKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback deleteKeyItem`);
let throwObject = {isThrow: false};
try {
......@@ -1303,7 +1307,7 @@ async function testAgree() {
应用在派生密钥时建议传入[HuksKeyStorageType](../reference/apis/js-apis-huks.md#hukskeystoragetype)中定义的类型;从API10开始应用只能选择存储(HUKS_STORAGE_ONLY_USED_IN_HUKS),或者选择导出(HUKS_STORAGE_KEY_EXPORT_ALLOWED),若不传入,则默认同时支持存储和导出,存在安全问题,不推荐业务使用。
```ts
```js
/*
* 以下以HKDF256密钥的Promise操作使用为例
*/
......@@ -1421,7 +1425,7 @@ function StringToUint8Array(str) {
return new Uint8Array(arr);
}
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function generateKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -1438,7 +1442,7 @@ function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObj
});
}
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicGenKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback generateKeyItem`);
let throwObject = {isThrow: false};
try {
......@@ -1458,7 +1462,7 @@ async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
}
}
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
function initSession(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.initSession(keyAlias, huksOptions, function (error, data) {
......@@ -1475,7 +1479,7 @@ function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject)
});
}
async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicInitFunc(keyAlias, huksOptions) {
console.info(`enter callback doInit`);
let throwObject = {isThrow: false};
try {
......@@ -1496,7 +1500,7 @@ async function publicInitFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
}
}
function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
function updateSession(handle, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.updateSession(handle, huksOptions, function (error, data) {
......@@ -1513,7 +1517,7 @@ function updateSession(handle:number, huksOptions:huks.HuksOptions, throwObject)
});
}
async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
async function publicUpdateFunc(handle, huksOptions) {
console.info(`enter callback doUpdate`);
let throwObject = {isThrow: false};
try {
......@@ -1533,7 +1537,7 @@ async function publicUpdateFunc(handle:number, huksOptions:huks.HuksOptions) {
}
}
function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
function finishSession(handle, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.finishSession(handle, huksOptions, function (error, data) {
......@@ -1550,7 +1554,7 @@ function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject)
});
}
async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
async function publicFinishFunc(handle, huksOptions) {
console.info(`enter callback doFinish`);
let throwObject = {isThrow: false};
try {
......@@ -1571,7 +1575,7 @@ async function publicFinishFunc(handle:number, huksOptions:huks.HuksOptions) {
}
}
function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function deleteKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.deleteKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -1588,7 +1592,7 @@ function deleteKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObjec
});
}
async function publicDeleteKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicDeleteKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback deleteKeyItem`);
let throwObject = {isThrow: false};
try {
......@@ -1689,379 +1693,379 @@ HUKS提供了全面完善的密钥访问控制能力,确保存储在HUKS中的
1. 生成密钥并指定指纹访问控制和相关属性
```ts
import huks from '@ohos.security.huks';
```js
import huks from '@ohos.security.huks';
/*
* 确定密钥别名和封装密钥属性参数集
*/
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,
}
// 指定密钥身份认证的类型:指纹
properties[5] = {
tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE,
value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT
}
// 指定密钥安全授权的类型(失效类型):新录入生物特征(指纹)后无效
properties[6] = {
tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE,
value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL
}
// 指定挑战值的类型:默认类型
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())
}
/*
* 确定密钥别名和封装密钥属性参数集
*/
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,
}
// 指定密钥身份认证的类型:指纹
properties[5] = {
tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE,
value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT
}
// 指定密钥安全授权的类型(失效类型):新录入生物特征(指纹)后无效
properties[6] = {
tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE,
value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL
}
// 指定挑战值的类型:默认类型
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())
}
/*
* 生成密钥
*/
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 generateKeyItem(keyAlias, 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 publicGenKeyFunc(keyAlias, 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);
}
```
async function TestGenKeyForFingerprintAccessControl() {
await publicGenKeyFunc(keyAlias, huksOptions);
}
```
2. 初始化密钥会话获取挑战值并发起指纹认证获取认证令牌
```ts
import huks from '@ohos.security.huks';
import userIAM_userAuth from '@ohos.userIAM.userAuth';
/*
* 确定密钥别名和封装密钥属性参数集
*/
let srcKeyAlias = 'sm4_key_fingerprint_access';
let handle;
let challenge;
let fingerAuthToken;
let authType = userIAM_userAuth.UserAuthType.FINGERPRINT;
let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1;
/* 集成生成密钥参数集 & 加密参数集 */
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<huks.HuksSessionHandle> {
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}`);
}
}
```js
import huks from '@ohos.security.huks';
import userIAM_userAuth from '@ohos.userIAM.userAuth';
function userIAMAuthFinger(huksChallenge:Uint8Array) {
// 获取认证对象
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);
}
// 订阅认证结果
try {
auth.on("result", {
callback: (result: userIAM_userAuth.AuthResultInfo) => {
/* 认证成功获取认证令牌 */
fingerAuthToken = result.token;
}
});
console.log("subscribe authentication event success");
} catch (error) {
console.log("subscribe authentication event failed " + error);
}
// 开始认证
try {
auth.start();
console.info("authV9 start auth success");
} catch (error) {
console.info("authV9 start auth failed, error = " + error);
}
}
/*
* 确定密钥别名和封装密钥属性参数集
*/
let srcKeyAlias = 'sm4_key_fingerprint_access';
let handle;
let challenge;
let fingerAuthToken;
let authType = userIAM_userAuth.UserAuthType.FINGERPRINT;
let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1;
async function testInitAndAuthFinger() {
/* 初始化密钥会话获取挑战值 */
await publicInitFunc(srcKeyAlias, huksOptions);
/* 调用userIAM进行身份认证 */
userIAMAuthFinger(challenge);
}
```
/* 集成生成密钥参数集 & 加密参数集 */
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())
}
3. 传入认证令牌进行数据操作
function initSession(keyAlias, huksOptions, throwObject) {
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);
}
});
}
```ts
/*
* 以下以SM4 128密钥的Callback操作使用为例
*/
import huks from '@ohos.security.huks';
async function publicInitFunc(keyAlias, 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}`);
}
}
/*
* 确定密钥别名和封装密钥属性参数集
*/
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;
/* 集成生成密钥参数集 & 加密参数集 */
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 userIAMAuthFinger(huksChallenge) {
// 获取认证对象
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);
}
function StringToUint8Array(str) {
let arr = [];
for (let i = 0, j = str.length; i < j; ++i) {
arr.push(str.charCodeAt(i));
}
return new Uint8Array(arr);
}
// 订阅认证结果
try {
auth.on("result", {
callback: (result) => {
/* 认证成功获取认证令牌 */
fingerAuthToken = result.token;
}
});
console.log("subscribe authentication event success");
} catch (error) {
console.log("subscribe authentication event failed " + error);
}
function updateSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise<huks.HuksReturnResult> {
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);
}
});
}
// 开始认证
try {
auth.start();
console.info("authV9 start auth success");
} catch (error) {
console.info("authV9 start auth failed, error = " + 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}`);
}
}
async function testInitAndAuthFinger() {
/* 初始化密钥会话获取挑战值 */
await publicInitFunc(srcKeyAlias, huksOptions);
/* 调用userIAM进行身份认证 */
userIAMAuthFinger(challenge);
}
```
function finishSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise<huks.HuksReturnResult> {
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);
}
});
}
3. 传入认证令牌进行数据操作
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}`);
}
}
```js
/*
* 以下以SM4 128密钥的Callback操作使用为例
*/
import huks from '@ohos.security.huks';
async function testSm4Cipher() {
encryptOptions.inData = StringToUint8Array(cipherInData);
/* 传入认证令牌 */
await publicUpdateFunc(handle, fingerAuthToken, encryptOptions);
encryptUpdateResult = updateResult;
encryptOptions.inData = new Uint8Array(new Array());
/* 传入认证令牌 */
await publicFinishFunc(handle, fingerAuthToken, encryptOptions);
if (finishOutData === cipherInData) {
console.info('test finish encrypt err ');
} else {
console.info('test finish encrypt success');
}
}
```
/*
* 确定密钥别名和封装密钥属性参数集
*/
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;
### 细粒度用户身份认证访问控制
/* 集成生成密钥参数集 & 加密参数集 */
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())
}
该功能是基于已有[密钥访问控制](#密钥访问控制)能力的扩展,提供了基于生物特征和锁屏密码二次身份认证的细粒度访问控制能力,允许设置密钥在加密、解密、签名、验签、密钥协商、密钥派生的单个或多个场景时是否需要进行身份验证。比如,业务需要使用HUKS密钥加密保存账号密码信息等数据,要求在加密的时候不进行指纹等身份认证,解密的时候需要进行指纹等身份认证,这是就需要依赖HUKS提供细粒度的二次身份认证访问控制机制。
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, huksOptions, token, throwObject) {
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);
}
});
}
1. 基于用户身份认证访问控制的流程,在密钥生成阶段,通过额外指定用于细粒度用户身份认证访问控制的HuksTag:[HUKS_TAG_KEY_AUTH_PURPOSE](../reference/apis/js-apis-huks.md#hukstag)值,来指定在某种算法用途的情况下需要使用用户身份认证访问控制能力。
2. 基于用户身份认证访问控制的流程,在密钥使用阶段,业务无需再次指定HUKS_TAG_KEY_AUTH_PURPOSE值,同用户身份认证访问控制的开发流程。
async function publicUpdateFunc(handle, token, 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, huksOptions, token, throwObject) {
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, token, 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);
/* 传入认证令牌 */
await publicUpdateFunc(handle, fingerAuthToken, encryptOptions);
let encryptUpdateResult = updateResult;
encryptOptions.inData = new Uint8Array(new Array());
/* 传入认证令牌 */
await publicFinishFunc(handle, fingerAuthToken, encryptOptions);
if (finishOutData === cipherInData) {
console.info('test finish encrypt err ');
} else {
console.info('test finish encrypt success');
}
}
```
### 细粒度用户身份认证访问控制
该功能是基于已有[密钥访问控制](#密钥访问控制)能力的扩展,提供了基于生物特征和锁屏密码二次身份认证的细粒度访问控制能力,允许设置密钥在加密、解密、签名、验签、密钥协商、密钥派生的单个或多个场景时是否需要进行身份验证。比如,业务需要使用HUKS密钥加密保存账号密码信息等数据,要求在加密的时候不进行指纹等身份认证,解密的时候需要进行指纹等身份认证,这是就需要依赖HUKS提供细粒度的二次身份认证访问控制机制。
**开发流程**
1. 基于用户身份认证访问控制的流程,在密钥生成阶段,通过额外指定用于细粒度用户身份认证访问控制的HuksTag:[HUKS_TAG_KEY_AUTH_PURPOSE](../reference/apis/js-apis-huks.md#hukstag)值,来指定在某种算法用途的情况下需要使用用户身份认证访问控制能力。
2. 基于用户身份认证访问控制的流程,在密钥使用阶段,业务无需再次指定HUKS_TAG_KEY_AUTH_PURPOSE值,同用户身份认证访问控制的开发流程。
**接口说明**
......@@ -2083,421 +2087,422 @@ HUKS提供了全面完善的密钥访问控制能力,确保存储在HUKS中的
1. 生成密钥并指定指纹访问控制和相关属性,以及HUKS_TAG_KEY_AUTH_PURPOSE值
```ts
import huks from '@ohos.security.huks';
```js
import huks from '@ohos.security.huks';
/*
* 确定密钥别名和封装密钥属性参数集
*/
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,
}
// 指定密钥身份认证的类型:指纹
properties[5] = {
tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE,
value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT
}
// 指定密钥安全授权的类型(失效类型):新录入生物特征(指纹)后无效
properties[6] = {
tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE,
value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL
}
// 指定挑战值的类型:默认类型
properties[7] = {
tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE,
value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL
}
// 指定某种算法用途时需要用户身份认证访问控制:比如解密需要
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())
}
/*
* 确定密钥别名和封装密钥属性参数集
*/
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,
}
// 指定密钥身份认证的类型:指纹
properties[5] = {
tag: huks.HuksTag.HUKS_TAG_USER_AUTH_TYPE,
value: huks.HuksUserAuthType.HUKS_USER_AUTH_TYPE_FINGERPRINT
}
// 指定密钥安全授权的类型(失效类型):新录入生物特征(指纹)后无效
properties[6] = {
tag: huks.HuksTag.HUKS_TAG_KEY_AUTH_ACCESS_TYPE,
value: huks.HuksAuthAccessType.HUKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL
}
// 指定挑战值的类型:默认类型
properties[7] = {
tag: huks.HuksTag.HUKS_TAG_CHALLENGE_TYPE,
value: huks.HuksChallengeType.HUKS_CHALLENGE_TYPE_NORMAL
}
// 指定某种算法用途时需要用户身份认证访问控制:比如解密需要
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 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 generateKeyItem(keyAlias, 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 publicGenKeyFunc(keyAlias, 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);
}
```
async function TestGenKeyForFingerprintAccessControl() {
await publicGenKeyFunc(keyAlias, huksOptions);
}
```
2. 使用密钥-加密场景-加密时不需要进行用户身份认证访问控制
```ts
```js
import huks from '@ohos.security.huks';
/*
* 确定密钥别名和封装密钥属性参数集
*/
let srcKeyAlias = 'sm4_key_fingerprint_access';
let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; // 明文数据
let IV = '1234567890123456';
let handle;
let cipherText; // 加密后的密文数据
function StringToUint8Array(str) {
let arr = [];
for (let i = 0, j = str.length; i < j; ++i) {
arr.push(str.charCodeAt(i));
}
return new Uint8Array(arr);
}
/*
* 确定密钥别名和封装密钥属性参数集
*/
let srcKeyAlias = 'sm4_key_fingerprint_access';
let cipherInData = 'Hks_SM4_Cipher_Test_101010101010101010110_string'; // 明文数据
let IV = '1234567890123456';
let handle;
let cipherText; // 加密后的密文数据
/* 集成生成密钥参数集 & 加密参数集 */
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 initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
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);
}
});
}
/* 集成生成密钥参数集 & 加密参数集 */
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 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}`);
}
}
function initSession(keyAlias, huksOptions, throwObject) {
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);
}
});
}
function finishSession(handle:number, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult> {
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);
}
});
}
async function publicInitFunc(keyAlias, 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}`);
}
}
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 finishSession(handle, huksOptions, throwObject) {
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);
}
});
}
async function publicFinishFunc(handle, 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}`);
}
}
async function testSm4Cipher() {
/* 初始化密钥会话获取挑战值 */
await publicInitFunc(srcKeyAlias, encryptOptions);
async function testSm4Cipher() {
/* 初始化密钥会话获取挑战值 */
await publicInitFunc(srcKeyAlias, encryptOptions);
/* 加密 */
encryptOptions.inData = StringToUint8Array(cipherInData);
await publicFinishFunc(handle, encryptOptions);
}
```
/* 加密 */
encryptOptions.inData = StringToUint8Array(cipherInData);
await publicFinishFunc(handle, encryptOptions);
}
```
3. 使用密钥-解密场景-解密时需要进行用户身份认证访问控制
```ts
```js
import huks from '@ohos.security.huks';
import userIAM_userAuth from '@ohos.userIAM.userAuth';
/*
* 确定密钥别名和封装密钥属性参数集
*/
let srcKeyAlias = 'sm4_key_fingerprint_access';
let cipherText = 'r56ywtTJUQC6JFJ2VV2kZw=='; // 加密时得到的密文数据, 业务需根据实际加密结果修改
let IV = '1234567890123456';
let handle;
let finishOutData; // 解密后的明文数据
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);
}
import userIAM_userAuth from '@ohos.userIAM.userAuth';
/* 集成生成密钥参数集 & 加密参数集 */
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())
}
/*
* 确定密钥别名和封装密钥属性参数集
*/
let srcKeyAlias = 'sm4_key_fingerprint_access';
let cipherText = 'r56ywtTJUQC6JFJ2VV2kZw=='; // 加密时得到的密文数据, 业务需根据实际加密结果修改
let IV = '1234567890123456';
let handle;
let finishOutData; // 解密后的明文数据
let fingerAuthToken;
let challenge;
let authType = userIAM_userAuth.UserAuthType.FINGERPRINT;
let authTrustLevel = userIAM_userAuth.AuthTrustLevel.ATL1;
function initSession(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksSessionHandle> {
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);
}
});
}
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 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}`);
}
}
/* 集成生成密钥参数集 & 加密参数集 */
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 userIAMAuthFinger(huksChallenge:Uint8Array) {
// 获取认证对象
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);
}
// 订阅认证结果
try {
auth.on("result", {
callback: (result: userIAM_userAuth.AuthResultInfo) => {
/* 认证成功获取认证令牌 */
fingerAuthToken = result.token;
}
});
console.log("subscribe authentication event success");
} catch (error) {
console.log("subscribe authentication event failed " + error);
}
// 开始认证
try {
auth.start();
console.info("authV9 start auth success");
} catch (error) {
console.info("authV9 start auth failed, error = " + error);
}
}
function initSession(keyAlias, huksOptions, throwObject) {
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);
}
});
}
function finishSession(handle:number, huksOptions:huks.HuksOptions, token:Uint8Array, throwObject) : Promise<huks.HuksReturnResult> {
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 publicInitFunc(keyAlias, 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 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}`);
}
}
function userIAMAuthFinger(huksChallenge) {
// 获取认证对象
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);
}
// 订阅认证结果
try {
auth.on("result", {
callback: (result) => {
/* 认证成功获取认证令牌 */
fingerAuthToken = result.token;
}
});
console.log("subscribe authentication event success");
} catch (error) {
console.log("subscribe authentication event failed " + error);
}
async function testSm4Cipher() {
/* 初始化密钥会话获取挑战值 */
await publicInitFunc(srcKeyAlias, decryptOptions);
// 开始认证
try {
auth.start();
console.info("authV9 start auth success");
} catch (error) {
console.info("authV9 start auth failed, error = " + error);
}
}
/* 调用userIAM进行身份认证 */
userIAMAuthFinger(challenge);
function finishSession(handle, huksOptions, token, throwObject) {
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);
}
});
}
/* 认证成功后进行解密, 需要传入Auth获取到的authToken值 */
decryptOptions.inData = StringToUint8Array(cipherText);
await publicFinishFunc(handle, fingerAuthToken, decryptOptions);
}
```
async function publicFinishFunc(handle, token, 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() {
/* 初始化密钥会话获取挑战值 */
await publicInitFunc(srcKeyAlias, decryptOptions);
/* 调用userIAM进行身份认证 */
userIAMAuthFinger(challenge);
/* 认证成功后进行解密, 需要传入Auth获取到的authToken值 */
decryptOptions.inData = StringToUint8Array(cipherText);
await publicFinishFunc(handle, fingerAuthToken, decryptOptions);
}
```
## 密钥证明
......@@ -2518,7 +2523,7 @@ HUKS为密钥提供合法性证明能力,主要应用于非对称密钥的公
**开发步骤**
```ts
```js
/*
* 以下以attestKey Callback接口操作验证为例
*/
......@@ -2601,7 +2606,7 @@ function StringToUint8Array(str) {
return new Uint8Array(arr);
}
function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) {
function generateKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.generateKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -2618,7 +2623,7 @@ function generateKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObj
});
}
async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicGenKeyFunc(keyAlias, huksOptions) {
console.info(`enter callback generateKeyItem`);
let throwObject = {isThrow: false};
try {
......@@ -2638,7 +2643,7 @@ async function publicGenKeyFunc(keyAlias:string, huksOptions:huks.HuksOptions) {
}
}
function attestKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObject) : Promise<huks.HuksReturnResult>{
function attestKeyItem(keyAlias, huksOptions, throwObject) {
return new Promise((resolve, reject) => {
try {
huks.attestKeyItem(keyAlias, huksOptions, function (error, data) {
......@@ -2655,7 +2660,7 @@ function attestKeyItem(keyAlias:string, huksOptions:huks.HuksOptions, throwObjec
});
}
async function publicAttestKey(keyAlias:string, huksOptions:huks.HuksOptions) {
async function publicAttestKey(keyAlias, huksOptions) {
console.info(`enter callback attestKeyItem`);
let throwObject = {isThrow: false};
try {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册