• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 通用密钥库设备开发指导
2
3## 概述
4
5### 功能简介
6
7OpenHarmony通用密钥库系统(英文全称:Open**H**armony **U**niversal **K**ey**S**tore,以下简称HUKS)是OpenHarmony提供的系统级的密钥管理系统服务,提供密钥的全生命周期管理能力,包括密钥生成、密钥存储、密钥使用、密钥销毁等功能,以及对存储在HUKS中的密钥提供合法性证明。在HUKS的分层架构中,处于最底层的HUKS核心层(HUKS Core)承载着密钥管理核心功能,一般运行在设备硬件安全环境中(比如TEE、安全芯片等)。由于不同厂商硬件安全环境不同,HUKS核心层的实现方式也不尽相同,为了保证服务层及应用层架构和接口的一致性,HUKS核心层定义了一套HDI接口(硬件设备统一接口),以保证HUKS服务层调用HUKS核心层的兼容。本文基于HUKS HDI接口,提供HUKS核心层功能的开发指导。
8
9HUKS核心层需要支持以下功能:
10
111. 生成密钥
12
132. 外部导入密钥
14
153. 密钥操作(加密解密、签名验签、密钥派生、密钥协商、消息认证码等)
16
174. 密钥访问控制
18
195. 密钥证明
20
216. 芯片平台公钥导出
22
23### 基本概念
24
25- **HUKS Core**
26
27  HUKS核心组件,承载HUKS的核心功能,包括密钥的密码学运算、明文密钥的加解密、密钥访问控制等。一般运行在设备的安全环境中(如TEE、安全芯片等,不同的厂商有所不同),保证密钥明文不出HUKS Core。
28
29
30- **密钥会话**
31
32  应用通过指定密钥别名,给当前操作的密钥建立一个会话,HUKS为每个会话生成一个全局唯一的句柄值来索引该会话。它的作用是缓存密钥使用期间的信息,包括操作数据、密钥信息、访问控制属性等。密钥操作一般需要经过**建立会话、传入数据和参数、结束会话(中止会话)** 三个阶段。
33
34
35- **可信执行环境(Trusted Execution Environment)**
36
37  通过划分软件和硬件资源的方法构建一个安全区域,使得安全区域内部的程序和数据得到保护。这种划分会分隔出两个执行环境——可信执行环境和普通执行环境。每个执行环境有独立的内部数据通路和计算所需存储空间,保证可信执行环境里的信息不会向外泄露。普通执行环境的应用不能访问可信执行环境的资源,可信执行环境中的应用在没有授权的情况下也无法相互访问。
38
39
40## 实现原理
41
42HUKS采用分层架构,包含应用层、服务层、核心层(领域层),其中应用层主要对应用提供接口,服务层处理应用的密钥管理请求,进行密钥的密文管理、身份校验、密钥会话管理等,核心层提供密钥生成、密钥操作、密钥访问控制和密钥证明等核心功能。
43
44**图1** HUKS分层架构图
45
46![huks_architect](./figures/HUKS-architecture.png)
47
48## 约束与限制
49
50 - **密钥不出安全环境**
51
52   HUKS的核心特点是密钥全生命周期明文不出HUKS Core,在有硬件条件的设备上,如有TEE(Trusted Execution Environment)或安全芯片的设备,HUKS Core运行在硬件安全环境中。即使REE(Rich Execution Environment)环境被攻破,也能确保密钥明文也不会泄露。因此,HUKS直通式HDI API所有函数接口密钥材料数据只能是密文格式。
53
54- **系统级安全加密存储**
55
56  必须基于设备根密钥加密业务密钥,在有条件的设备上,叠加用户口令加密保护密钥。
57
58- **严格的访问控制**
59
60  只有合法的业务才有权访问密钥,同时支持用户身份认证访问控制以支持业务的高安敏感场景下安全访问密钥的诉求。
61- **密钥的合法性证明**
62
63  业务提供硬件厂商级别的密钥的合法性证明,证明密钥没有被篡改,并确实存在于有硬件保护的HUKS Core中,以及拥有正确的密钥属性。
64
65- **密钥材料格式**
66
67  导入/导出密钥时(包括密钥对、公钥、私钥),密钥材料的数据格式必须满足HUKS要求的格式,具体各个密码算法密钥材料见[密钥材料格式](../../application-dev/security/UniversalKeystoreKit/huks-concepts.md#密钥材料格式)。
68
69- **证书链格式**
70
71  AttestKey返回的证书链应该按照业务证书、设备证书、CA证书和根证书的顺序组装,在每项证书之前还需要加上证书的长度。证书链组装完成后添加整个证书链的长度组装成Blob格式。证书的具体格式如要自己实现应与服务器侧解析的格式相对应。
72
73  ![CertChain格式图](figures/HUKS-CertChain.png)
74
75- **KeyBlob格式**
76
77  接口返回的密钥必须按照密钥存储态组装成KeyBlob,哪些接口需要遵循该限制请见[接口说明](#接口说明)。
78
79  ![KeyBlob格式图](figures/HUKS-KeyBlob.png)
80
81## 开发指导
82
83### 场景介绍
84
85HUKS Core作为向应用提供密钥库能力的基础,包括密钥管理及密钥的密码学操作等功能。如果想要使用自己的实现替换HUKS Core,需要实现以下接口。
86
87### 接口说明
88
89**表1** 接口功能介绍
90
91| 接口名                                                       | 功能介绍                                  | 约束与限制                     | 对应的js接口                                        |
92| ------------------------------------------------------------ | ---------------------------------------- | ----------------------------- | ------------------------------------------------------------ |
93| [ModuleInit()](#moduleinit)                   | HUKS Core的初始化。                            |  无                           | 无 |
94| [ModuleDestroy()](#moduledestroy)                   | HUKS Core的销毁。                            |  无                           | 无 |无                            | 无 |
95| [GenerateKey()](#generatekey)                  | 根据密码算法参数,生成密钥,并返回密文材料。                                |  出参要遵循KeyBlob格式          |generateKey(keyAlias: string, options: HuksOptions)|
96| [ImportKey()](#importkey)                     | 导入明文密钥,并返回密文材料。                            |  出参要遵循KeyBlob格式           | importKey(keyAlias: string, options: HuksOptions)|
97| [ImportWrappedKey()](#importwrappedkey)        |导入加密密钥,并返回密文材料。                              |  出参要遵循KeyBlob格式          | importWrappedKey(keyAlias: string, wrappingKeyAlias: string, options: HuksOptions)|
98| [ExportPublicKey()](#exportpublickey)         | 导出密钥对中的公钥。                                 |无                             | exportKey(keyAlias: string, options: HuksOptions) |
99| [Init()](#init)                              | 初始化密钥会话的接口,返回密钥会话句柄和令牌(可选)。                       |无                              | init(keyAlias: string, options: HuksOptions) |
100| [Update()](#update)                           | 追加密钥操作数据。                     |签名验签时入参是原始数据          | update(handle: number, token?: Uint8Array, options: HuksOptions) |
101| [Finish()](#finish)                           | 结束密钥会话                     |签名验签时入参是签名后数据        | finish(handle: number, options: HuksOptions) |
102| [Abort()](#abort)                         | 取消密钥会话                               |无                             | abort(handle: number, options: HuksOptions) |
103| [CheckKeyValidity()](#checkkeyvalidity)        | 校验密钥材料(密文)的完整性                              |无                            | 无 |
104| [AttestKey()](#attestkey)        | 获取密钥证书。                              |出参要遵循密钥证书链格式                      | attestKey(keyAlias: string, options: HuksOptions)|
105| [ExportChipsetPlatformPublicKey()](#exportchipsetplatformpublickey)        | 导出芯片平台级密钥对的公钥。     | 出参为ECC P256的x y轴值裸数据,各32字节                      | 无 |
106| [UpgradeKey()](#upgradekey)        | 升级密钥文件。     | 无                      | 无 |
107| [GenerateRandom()](#generaterandom)        | 生成安全随机数     | 无                      | 无 |
108| [Encrypt()](#encrypt)        | 加密     | 无                      | 无 |
109| [Decrypt()](#decrypt)        | 解密     | 无                      | 无 |
110| [Sign()](#sign)        | 签名     | 无                      | 无 |
111| [Verify()](#verify)        | 验签     | 无                      | 无 |
112| [AgreeKey()](#agreekey)        | 密钥协商     | 无                      | 无 |
113| [DeriveKey()](#derivekey)        | 密钥派生     | 无                      | 无 |
114| [Mac()](#mac)        | 消息认证码     | 无                      | 无 |
115
116
117
118#### ModuleInit
119
120**接口原型**
121```
122int32_t ModuleInit(struct IHuks *self);
123```
124
125**接口描述**
126
127HUKS Core的初始化,一般用于初始化全局变量,比如全局线程锁,算法库,用于访问控制的AuthToken Key和根密钥。
128
129**参数说明**
130
131| 名称 | 描述 |
132| ------ | ---- |
133|self| HUKS HDI函数指针结构体指针 |
134
135**返回值**
136
137- HKS_SUCCESS:表示成功,值为0。
138- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)139
140#### ModuleDestroy
141
142**接口原型**
143```
144int32_t ModuleDestroy(struct IHuks *self);
145```
146
147**接口描述**
148
149HUKS Core的销毁,一般用于释放全局变量,包括锁,销毁内存中的AuthToken Key和根密钥等。
150
151
152**参数说明**
153
154| 名称 | 描述 |
155| ------ | ---- |
156|self| HUKS HDI函数指针结构体指针 |
157
158
159**返回值**
160
161- HKS_SUCCESS:表示成功,值为0。
162- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)163
164
165#### GenerateKey
166
167**接口原型**
168```
169int32_t GenerateKey(struct IHuks *self, const struct HuksBlob *keyAlias, const struct HuksParamSet *paramSet, const struct HuksBlob *keyIn, struct HuksBlob *encKeyOut);
170```
171
172**接口描述**
173
174根据密钥属性paramSet生成密钥。
175
176**参数说明**
177
178| 名称 | 描述 |
179| ------ | ---- |
180|self| HUKS HDI函数指针结构体指针。 |
181|keyAlias | 将要生成的密钥的别名,要求:<br>1. keyAlias != null <br>2. keyAlias -> data != null<br>3. keyAlias -> dataLen != 0 |
182|paramSet | 要生成密钥的参数。 |
183|keyIn | 可选,通过密钥协商或密钥派生生成密钥时,传原密钥材料。|
184|encKeyOut | 出参,密钥密文材料,将密钥属性paramset和生成的密钥密文存放在这里,格式参考KeyBlob。|
185
186**约束与限制**
187
188- 请在接口内检查上述参数是否符合要求,如是否是空指针、密钥算法是否支持等。
189- encKeyOut请参照KeyBlob的结构。
190
191**返回值**
192
193- HKS_SUCCESS:表示成功,值为0。
194- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)195
196
197#### ImportKey
198
199**接口原型**
200```
201int32_t ImportKey(struct IHuks *self, const struct HuksBlob *keyAlias, const struct HuksBlob *key, const struct HuksParamSet *paramSet, struct HuksBlob *encKeyOut);
202```
203
204**接口描述**
205
206导入明文密钥。
207
208**参数说明**
209
210| 名称 | 描述 |
211| ------ | ---- |
212|self| HUKS HDI函数指针结构体指针。 |
213|keyAlias | 待导入的密钥的别名,要求:<br>1. keyAlias != null <br>2. keyAlias -> data != null<br>3. keyAlias -> dataLen != 0 |
214|key | 待导入的密钥明文材料,密钥材料格式见[密钥材料格式](../../application-dev/security/UniversalKeystoreKit/huks-concepts.md),要求: <br>1. key != null  <br>2. key -> data != null <br>3. key -> dataLen != 0 |
215|paramSet | 待导入密钥的参数。 |
216|encKeyOut | 出参,密钥密文材料,将密钥属性paramset和生成的密钥密文存放在这里,格式参考KeyBlob。|
217
218**约束与限制**
219
220- 请在接口内检查上述参数是否符合要求,如是否是空指针、密钥算法是否支持等。
221- encKeyOut请参照KeyBlob的结构。
222
223**返回值**
224
225- HKS_SUCCESS:表示成功,值为0。
226- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)227
228
229#### ImportWrappedKey
230
231**接口原型**
232```
233int32_t ImportWrappedKey(struct IHuks *self, const struct HuksBlob *wrappingKeyAlias, const struct HuksBlob *wrappingEncKey, const struct HuksBlob *wrappedKeyData, const struct HuksParamSet *paramSet, struct HuksBlob *encKeyOut);
234```
235
236**接口描述**
237
238导入加密密钥。
239
240**参数说明**
241
242| 名称 | 描述 |
243| ------ | ---- |
244|self| HUKS HDI函数指针结构体指针。 |
245|wrappingKeyAlias | 用于做加密导入的密钥的别名(非导入密钥本身的别名),要求:<br>1. wrappingKeyAlias != null <br>2. wrappingKeyAlias -> data != null <br>3. wrappingKeyAlias -> dataLen != 0 |
246|wrappingEncKey | 要导入的密钥数据被加密时使用的密钥,要求:<br>1. wrappingEncKey != null <br>2. wrappingEncKey -> data != null <br>3. wrappingEncKey -> dataLen != 0 |
247|wrappedKeyData | 要导入的密钥的密钥材料数据,格式参考[加密导入材料格式](../../application-dev/security/UniversalKeystoreKit/huks-concepts.md),要求:<br>1. wrappedKeyData != null <br>2. wrappedKeyData -> data != null <br>3. wrappedKeyData -> dataLen != 0 |
248|paramSet | 待导入密钥的密钥属性。|
249|encKeyOut | 导入密钥的密文材料,参考KeyBlob格式。|
250
251**约束与限制**
252
253- 请在接口内检查上述参数是否符合要求,如是否是空指针、密钥算法是否支持等。
254- encKeyOut请参照KeyBlob的结构。
255
256**返回值**
257
258- HKS_SUCCESS:表示成功,值为0。
259- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)260
261
262#### ExportPublicKey
263
264**接口原型**
265```
266int32_t ExportPublicKey(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, struct HuksBlob *keyOut);
267```
268
269**接口描述**
270
271导出密钥对的公钥。
272
273**参数说明**
274
275| 名称 | 描述 |
276| ------ | ---- |
277|self| HUKS HDI函数指针结构体指针。 |
278|encKey| 与要导出的公钥的密钥对材料,要求:<br>1. encKey != null <br>2. encKey -> data != null<br>3. encKey -> dataLen != 0 |
279|paramSet | 导出公钥的所需要的参数,默认为空。 |
280|keyOut | 出参,存放导出的公钥。|
281
282**返回值**
283
284- HKS_SUCCESS:表示成功,值为0。
285- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)286
287
288#### Init
289
290**接口原型**
291```
292int32_t Init(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, struct HuksBlob *handle, struct HuksBlob *token);
293```
294
295**接口描述**
296
297初始化密钥会话的接口,传入密钥材料密文,在HUKS Core进行解密,并生成密钥会话句柄和令牌(按需)。
298
299**参数说明**
300
301| 名称 | 描述 |
302| ------ | ---- |
303|self| HUKS HDI函数指针结构体指针。 |
304|encKey| 待操作密钥的密文材料,要求:<br>1. encKey != null <br>2. encKey -> data != null<br>3. encKey -> dataLen != 0 |
305|paramSet | 初始化密钥会话的参数。 |
306|handle | 出参,密钥会话的句柄,作为Update、Finish和Abort的入参,用于索引密钥会话。|
307|token | 出参,存放密钥访问控制的认证令牌(按需)。|
308
309**约束与限制**
310
311密钥会话操作函数,业务配合Update、Finish、Abort使用。
312
313**返回值**
314
315- HKS_SUCCESS:表示成功,值为0。
316- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)317
318
319#### Update
320
321**接口原型**
322```
323int32_t Update(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData, struct HuksBlob *outData);
324```
325
326**接口描述**
327
328追加密钥操作数据,如密码算法的要求需要对数据进行分段操作。
329
330**参数说明**
331
332| 名称 | 描述 |
333| ------ | ---- |
334|self| HUKS HDI函数指针结构体指针。 |
335|handle | 密钥会话的句柄。|
336|paramSet | 追加操作的参数。|
337|inData | 追加操作的输入。|
338|outData | 追加操作的结果。|
339
340**约束与限制**
341
342- 密钥会话操作函数,业务配合Init、Finish、Abort使用。
343- 在进行签名验签时inData要传入原文数据。
344
345**返回值**
346
347- HKS_SUCCESS:表示成功,值为0。
348- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)349
350
351#### Finish
352
353**接口原型**
354```
355int32_t Finish(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData, struct HuksBlob *outData);
356```
357
358**接口描述**
359
360结束密钥会话,操作最后一段数据并结束密钥会话。
361
362**参数说明**
363
364| 名称 | 描述 |
365| ------ | ---- |
366|self| HUKS HDI函数指针结构体指针。 |
367|handle | 密钥会话的句柄。|
368|paramSet | 最后一段操作的参数。|
369|inData | 最后一段操作的输入。|
370|outData | 密钥操作的结果。|
371
372**约束与限制**
373
374- 密钥会话操作函数,业务配合Init、Update、Abort使用。
375- 在进行验签时inData要传入需要验证的签名数据,通过返回结果表示验签是否成功。
376
377**返回值**
378
379- HKS_SUCCESS:表示成功,值为0。
380- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)381
382
383#### Abort
384
385**接口原型**
386```
387int32_t Abort(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet);
388```
389
390**接口描述**
391
392取消密钥会话。当Init,Update和Finish操作中的任一阶段发生错误时,都要调用abort来终止密钥会话。
393
394**参数说明**
395
396| 名称 | 描述 |
397| ------ | ---- |
398|self| HUKS HDI函数指针结构体指针。 |
399|handle | 密钥会话的句柄。|
400|paramSet | Abort操作的参数。|
401
402**约束与限制**
403
404密钥会话操作函数,业务配合Init、Update、Finish使用。
405
406**返回值**
407
408- HKS_SUCCESS:表示成功,值为0。
409- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)410
411
412#### CheckKeyValidity
413
414**接口原型**
415```
416int32_t CheckKeyValidity(struct IHuks *self, const struct HuksParamSet *paramSet, const struct HuksBlob *encKey);
417```
418
419**接口描述**
420
421获取密钥属性。
422
423**参数说明**
424
425| 名称 | 描述 |
426| ------ | ---- |
427|self| HUKS HDI函数指针结构体指针。 |
428|paramSet | 用于校验密钥完整性接口的参数,默认传空。|
429|encKey | 待校验密钥完整性的密钥材料(密文)。|
430
431**返回值**
432
433- HKS_SUCCESS:表示成功,值为0。
434- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)435
436
437
438#### AttestKey
439
440**接口原型**
441```
442int32_t AttestKey(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, struct HuksBlob *certChain);
443```
444
445**接口描述**
446
447获取密钥证书。
448
449**参数说明**
450
451| 名称 | 描述 |
452| ------ | ---- |
453|self| HUKS HDI函数指针结构体指针。 |
454|encKey| 要获取证书的密钥对材料密文。|
455|paramSet |获取密钥证书操作的参数,如challenge等。|
456|certChain |出参,存放证书链,格式参考上述证书链格式。|
457
458**约束与限制**
459
460certChain的格式需遵循[约束与限制第二点](#约束与限制)。
461
462
463**返回值**
464
465- HKS_SUCCESS:表示成功,值为0。
466- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)467
468
469#### ExportChipsetPlatformPublicKey
470
471**接口原型**
472```
473int32_t ExportChipsetPlatformPublicKey(struct IHuks *self, const struct HuksBlob *salt, enum HuksChipsetPlatformDecryptScene scene, struct HuksBlob *publicKey);
474```
475
476**接口描述**
477
478导出芯片平台级密钥对的公钥。
479
480**参数说明**
481
482| 名称 | 描述 |
483| ------ | ---- |
484|self| HUKS HDI函数指针结构体指针。 |
485|salt| 用来派生芯片平台密钥对时的派生因子。|
486|scene |业务预期进行芯片平台解密的场景。|
487|publicKey |出参为ECC P256的x y轴值裸数据,各32字节。|
488
489
490**约束与限制**
491
492入参`salt`长度必须为16字节,且最后一个字节的内容会被忽略,将由huks内部根据入参`scene`进行修改填充。
493
494当前huks的芯片平台级密钥对为软实现,硬编码了一对ECC-P256密钥对到代码中,`salt`值被忽略,即无论传入什么`salt`,派生出的密钥都是一样的。在真正基于硬件的芯片平台级密钥实现中,`salt`为用来派生密钥的派生因子,传入不同的`salt`会得到不同的密钥对。
495
496**返回值**
497
498- HKS_SUCCESS:表示成功,值为0。
499- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)500
501
502#### UpgradeKey
503
504**接口原型**
505```
506int32_t UpgradeKey(struct IHuks *self, const struct HuksBlob *encOldKey, const struct HuksParamSet *paramSet, struct HuksBlob *encNewKey);
507```
508
509**接口描述**
510
511升级密钥文件。当密钥文件版本号小于最新版本号时,触发该升级能力。
512
513**参数说明**
514
515| 名称 | 描述 |
516| ------ | ---- |
517|self| HUKS HDI函数指针结构体指针。 |
518|encOldKey| 待升级的密钥文件数据。|
519|paramSet |升级密钥文件数据的参数。|
520|encNewKey |出参,升级后的密钥文件数据。|
521
522**返回值**
523
524- HKS_SUCCESS:表示成功,值为0。
525- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)526
527
528
529#### GenerateRandom
530
531**接口原型**
532```
533int32_t GenerateRandom(struct IHuks *self, const struct HuksParamSet *paramSet, struct HuksBlob *random);
534```
535
536**接口描述**
537
538生成安全随机数。
539
540**参数说明**
541
542| 名称 | 描述 |
543| ------ | ---- |
544|self| HUKS HDI函数指针结构体指针。 |
545|paramSet |待生成安全随机数的参数,如长度。|
546|random|出参,随机数。|
547
548**返回值**
549
550- HKS_SUCCESS:表示成功,值为0。
551- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)552
553
554#### Sign
555
556**接口原型**
557```
558int32_t Sign(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, const struct HuksBlob *srcData, struct HuksBlob *signature);
559```
560
561**接口描述**
562
563对数据进行签名
564
565**参数说明**
566
567| 名称 | 描述 |
568| ------ | ---- |
569|self| HUKS HDI函数指针结构体指针。 |
570|encKey |用于签名的密钥对材料(密文)。|
571|paramSet |用于签名的参数,如摘要模式。|
572|srcData | 用于签名的数据。|
573|signature |出参,数据签名。|
574
575**返回值**
576
577- HKS_SUCCESS:表示成功,值为0。
578- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)579
580
581#### Verify
582
583**接口原型**
584```
585int32_t Verify(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, const struct HuksBlob *srcData, const struct HuksBlob *signature);
586```
587
588**接口描述**
589
590对数据签名进行验签
591
592**参数说明**
593
594| 名称 | 描述 |
595| ------ | ---- |
596|self| HUKS HDI函数指针结构体指针。 |
597|encKey |用于验签的密钥对材料(密文)。|
598|paramSet |用于验签的参数,如摘要模式。|
599|srcData | 待验签的数据。|
600|signature | 用于验签的签名。|
601
602**返回值**
603
604- HKS_SUCCESS:表示成功,值为0。
605- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)606
607
608#### Encrypt
609
610**接口原型**
611```
612int32_t Encrypt(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, const struct HuksBlob *plainText, struct HuksBlob *cipherText);
613```
614
615**接口描述**
616
617对数据进行单次加密,相比密钥会话接口,该接口需满足一次调用即可完成加密操作
618
619**参数说明**
620
621| 名称 | 描述 |
622| ------ | ---- |
623|self| HUKS HDI函数指针结构体指针。 |
624|encKey |用于加密的密钥材料(密文)。|
625|paramSet |用于加密的密钥参数,如密钥工作模式、填充模式等。|
626|plainText| 待加密的数据明文。|
627|cipherText| 加密后的数据密文。|
628
629**返回值**
630
631- HKS_SUCCESS:表示成功,值为0。
632- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)633
634
635#### Decrypt
636
637**接口原型**
638```
639int32_t Decrypt(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, const struct HuksBlob *cipherText, struct HuksBlob *plainText);
640```
641
642**接口描述**
643
644对数据进行单次解密,相比密钥会话接口,该接口需要满足一次调用完成解密操作
645
646**参数说明**
647
648| 名称 | 描述 |
649| ------ | ---- |
650|self| HUKS HDI函数指针结构体指针。 |
651|encKey | 用于解密的密钥材料(密文)。|
652|paramSet |用于解密的密钥参数,如密钥工作模式、填充模式等。|
653|cipherText| 待解密的数据密文。|
654|plainText| 解密后的数据明文。|
655
656**返回值**
657
658- HKS_SUCCESS:表示成功,值为0。
659- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)660
661
662#### AgreeKey
663
664**接口原型**
665```
666int32_t AgreeKey(struct IHuks *self, const struct HuksParamSet *paramSet, const struct HuksBlob *encPrivateKey, const struct HuksBlob *peerPublicKey, struct HuksBlob *agreedKey);
667```
668
669**接口描述**
670
671对密钥进行协商,相比密钥会话接口,该接口需要满足一次调用完成密钥协商操作
672
673**参数说明**
674
675| 名称 | 描述 |
676| ------ | ---- |
677|self| HUKS HDI函数指针结构体指针。 |
678|paramSet |用于协商的参数,如协商密钥的长度。|
679|encPrivateKey|  用于协商的密钥对材料(密文)。|
680|peerPublicKey| 用于协商密钥对公钥(明文)。|
681|agreedKey |出参,协商出的密钥明文。|
682
683**返回值**
684
685- HKS_SUCCESS:表示成功,值为0。
686- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)687
688#### DeriveKey
689
690**接口原型**
691```
692int32_t DeriveKey(struct IHuks *self, const struct HuksParamSet *paramSet, const struct HuksBlob *encKdfKey, struct HuksBlob *derivedKey);
693```
694
695**接口描述**
696
697对密钥进行派生,相比密钥会话接口,该接口需要满足一次调用完成密钥派生操作
698
699**参数说明**
700
701| 名称 | 描述 |
702| ------ | ---- |
703|self| HUKS HDI函数指针结构体指针。 |
704|paramSet |用于密钥派生的参数,如派生密钥的长度。|
705|encKdfKey| 用于派生的密钥材料(密文)。|
706|derivedKey| 出参,派生出的密钥(明文)。|
707
708
709**返回值**
710
711- HKS_SUCCESS:表示成功,值为0。
712- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)713
714
715#### Mac
716
717**接口原型**
718```
719int32_t Mac(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet, const struct HuksBlob *srcData, struct HuksBlob *mac);
720```
721
722**接口描述**
723
724根据密钥生成消息认证码。
725
726**参数说明**
727
728| 名称 | 描述 |
729| ------ | ---- |
730|self| HUKS HDI函数指针结构体指针。 |
731|encKey| 用于生成消息认证码的密钥材料(密文)。|
732|paramSet | 用于生成消息认证码的参数。|
733|srcData | 消息数据。|
734|mac| 出参,消息认证码。|
735
736
737**返回值**
738
739- HKS_SUCCESS:表示成功,值为0。
740- 其他:表示失败,值为负数,具体参考[HksErrorCode枚举值定义](https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type_enum.h)741
742
743### 开发步骤
744
745#### 代码目录
746
7471. HDI接口的适配在以下目录中:
748
749    ```undefined
750    //drivers_peripheral/huks
751    ├── BUILD.gn # 编译脚本
752    ├── hdi_service # 实现依赖,通过dlopen方式引用libhuks_engine_core_standard.z.so(软实现的HUKS Core,仅用于参考)
753        ├── huks_sa_type.h # HUKS服务层的数据结构定义
754        ├── huks_sa_hdi_struct.h # libhuks_engine_core_standard.z.so中函数指针结构体的定义
755        ├── huks_hdi_template.h # HUKS服务层和HDI接口数据结构的转化适配
756        ├── huks_hdi_service.c # HUKS直通式HDI服务层的接口实现
757        └── huks_hdi_passthrough_adapter.c # HUKS直通式HDI服务层到软实现HUKS Core的适配层
758    └── test # HUKS HDI接口unittest和fuzztest
759        ├── BUILD.gn # 编译脚本
760        ├── fuzztest # fuzz测试
761        └── unittest # 单元测试
762    ```
763
7642. HUKS Core软实现的代码在以下目录中:
765
766    ```undefined
767    //base/security/huks/services/huks_standard/huks_engine
768    ├── BUILD.gn # 编译脚本
769    ├── core_dependency # HUKS Core依赖
770    └── core # HUKS Core层的软实现
771        ├── BUILD.gn # 编译脚本
772        ├── include
773        └── src
774            ├── hks_core_interfaces.c # HDI到HUKS Core的适配层
775            └── hks_core_service.c # HUKS Core详细实现
776            └── ... #其他功能代码
777    ```
778
779   > ![icon-caution.gif](public_sys-resources/icon-caution.gif) **注意:**
780   >
781   > HUKS Core软实现中存在硬编码相关敏感数据,包括根密钥、访问控制用的AuthToken密钥、加密AuthToken用的密钥、证书相关等,如设备开发者使用了相关代码,一定要替换成自有实现。
782
783
784   - **根密钥**
785
786     用于加密HUKS业务密钥,一般由设备根密钥派生而来,HUKS Core软实现中硬编码在代码中,详细代码见[hks_core_get_main_key.c](https://gitee.com/openharmony/security_huks/blob/master/frameworks/huks_standard/main/crypto_engine/crypto_common/src/hks_core_get_main_key.c)787
788   - **访问控制用于对AuthToken做HMAC的密钥**
789
790     用于UserIAM对AuthToken进行HMAC,HUKS Core软实现中硬编码在代码中,值为"huks_default_user_auth_token_key",详细代码见[hks_keyblob.c](https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/core/src/hks_keyblob.c)791
792   - **访问控制用于对AuthToken敏感字段加密的密钥**
793
794     用于UserIAM对AuthToken敏感字段进行加密的密钥,HUKS Core软实现中硬编码在代码中,值为"huks_default_user_auth_token_key",详细代码见[hks_keyblob.c](https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/core/src/hks_keyblob.c)795
796   - **根证书、设备CA、设备证书**
797
798     用于密钥证明,一般由设备证书管理模块预置在硬件设备安全存储当中,HUKS Core软实现中硬编码在代码中,详细代码见[dcm_certs_and_key.h](https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/device_cert_manager/include/dcm_certs_and_key.h)799
800#### 适配样例
801
802下文以HUKS Core中的密钥会话Init\Update\Finish接口适配作为一个样例,介绍基本流程,仅供参考不可实际运行,实际可运行代码参考[HUKS源码目录](https://gitee.com/openharmony/security_huks)
803
8041. 创建一个句柄,通过这个句柄在session中存储密钥操作相关的信息,使得外部可以通过这个句柄分多次进行同一密钥操作。
805
806   ```c
807
808   //密钥会话Init接口
809
810   int32_t HksCoreInit(const struct  HuksBlob *key, const struct HuksParamSet *paramSet, struct HuksBlob *handle,
811    struct HuksBlob *token)
812   {
813       HKS_LOG_D("HksCoreInit in Core start");
814       uint32_t pur = 0;
815       uint32_t alg = 0;
816       //检查参数
817       if (key == NULL || paramSet == NULL || handle == NULL || token == NULL) {
818           HKS_LOG_E("the pointer param entered is invalid");
819           return HKS_FAILURE;
820        }
821
822        if (handle->size < sizeof(uint64_t)) {
823            HKS_LOG_E("handle size is too small, size : %u", handle->size);
824            return HKS_ERROR_INSUFFICIENT_MEMORY;
825        }
826        //解密密钥文件
827        struct HuksKeyNode *keyNode = HksCreateKeyNode(key, paramSet);
828        if (keyNode == NULL || handle == NULL) {
829            HKS_LOG_E("the pointer param entered is invalid");
830            return HKS_ERROR_BAD_STATE;
831        }
832        //通过handle向session中存储信息,供Update/Finish使用。使得外部可以通过同个handle分多次进行同一密钥操作。
833        handle->size = sizeof(uint64_t);
834        (void)memcpy_s(handle->data, handle->size, &(keyNode->handle), handle->size);
835        //从参数中提取出算法
836        int32_t ret = GetPurposeAndAlgorithm(paramSet, &pur, &alg);
837        if (ret != HKS_SUCCESS) {
838            HksDeleteKeyNode(keyNode->handle);
839            return ret;
840        }
841        //检查密钥参数
842        ret = HksCoreSecureAccessInitParams(keyNode, paramSet, token);
843        if (ret != HKS_SUCCESS) {
844            HKS_LOG_E("init secure access params failed");
845            HksDeleteKeyNode(keyNode->handle);
846            return ret;
847        }
848        //通过密钥使用目的获取对应的算法库处理函数
849        uint32_t i;
850        uint32_t size = HKS_ARRAY_SIZE(g_hksCoreInitHandler);
851        for (i = 0; i < size; i++) {
852           if (g_hksCoreInitHandler[i].pur == pur) {
853               HKS_LOG_E("Core HksCoreInit [pur] = %d, pur = %d", g_hksCoreInitHandler[i].pur, pur);
854               ret = g_hksCoreInitHandler[i].handler(keyNode, paramSet, alg);
855               break;
856        }
857        }
858        //异常结果检查
859        if (ret != HKS_SUCCESS) {
860            HksDeleteKeyNode(keyNode->handle);
861            HKS_LOG_E("CoreInit failed, ret : %d", ret);
862            return ret;
863        }
864
865        if (i == size) {
866            HksDeleteKeyNode(keyNode->handle);
867            HKS_LOG_E("don't found purpose, pur : %u", pur);
868            return HKS_FAILURE;
869        }
870
871        HKS_LOG_D("HksCoreInit in Core end");
872        return ret;
873    }
874   ```
875
8762. 在执行密钥操作前通过句柄获得上下文信息,执行密钥操作时放入分片数据并取回密钥操作结果或者追加数据。
877
878    ```c
879    //密钥会话Update接口
880    int32_t HksCoreUpdate(const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData,
881        struct HuksBlob *outData)
882    {
883        HKS_LOG_D("HksCoreUpdate in Core start");
884        uint32_t pur = 0;
885        uint32_t alg = 0;
886        //检查参数
887        if (handle == NULL || paramSet == NULL || inData == NULL) {
888            HKS_LOG_E("the pointer param entered is invalid");
889            return HKS_FAILURE;
890        }
891
892        uint64_t sessionId;
893        struct HuksKeyNode *keyNode = NULL;
894        //根据handle获取本次密钥会话操作需要的上下文
895        int32_t ret = GetParamsForUpdateAndFinish(handle, &sessionId, &keyNode, &pur, &alg);
896        if (ret != HKS_SUCCESS) {
897            HKS_LOG_E("GetParamsForCoreUpdate failed");
898            return ret;
899        }
900        //校验密钥参数
901        ret = HksCoreSecureAccessVerifyParams(keyNode, paramSet);
902        if (ret != HKS_SUCCESS) {
903            HksDeleteKeyNode(sessionId);
904            HKS_LOG_E("HksCoreUpdate secure access verify failed");
905            return ret;
906        }
907        //调用对应的算法库密钥处理函数
908        uint32_t i;
909        uint32_t size = HKS_ARRAY_SIZE(g_hksCoreUpdateHandler);
910        for (i = 0; i < size; i++) {
911            if (g_hksCoreUpdateHandler[i].pur == pur) {
912                struct HuksBlob appendInData = { 0, NULL };
913                ret = HksCoreAppendAuthInfoBeforeUpdate(keyNode, pur, paramSet, inData, &appendInData);
914                if (ret != HKS_SUCCESS) {
915                    HKS_LOG_E("before update: append auth info failed");
916                    break;
917                }
918                ret = g_hksCoreUpdateHandler[i].handler(keyNode, paramSet,
919                     appendInData.data == NULL ? inData : &appendInData, outData, alg);
920                if (appendInData.data != NULL) {
921                    HKS_FREE_BLOB(appendInData);
922                }
923                break;
924            }
925        }
926        //异常结果检查
927        if (ret != HKS_SUCCESS) {
928            HksDeleteKeyNode(keyNode->handle);
929            HKS_LOG_E("CoreUpdate failed, ret : %d", ret);
930            return ret;
931        }
932
933        if (i == size) {
934            HksDeleteKeyNode(sessionId);
935            HKS_LOG_E("don't found purpose, pur : %u", pur);
936            return HKS_FAILURE;
937        }
938        return ret;
939    }
940    ```
941
9423. 结束密钥操作并取回结果,销毁句柄。
943
944   ```c
945   //密钥会话Finish接口
946   int32_t HksCoreFinish(const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData,
947    struct HuksBlob *outData)
948   {
949       HKS_LOG_D("HksCoreFinish in Core start");
950       uint32_t pur = 0;
951       uint32_t alg = 0;
952       //检查参数
953       if (handle == NULL || paramSet == NULL || inData == NULL) {
954           HKS_LOG_E("the pointer param entered is invalid");
955           return HKS_FAILURE;
956       }
957
958       uint64_t sessionId;
959       struct HuksKeyNode *keyNode = NULL;
960       //根据handle获取本次密钥会话操作需要的上下文
961       int32_t ret = GetParamsForUpdateAndFinish(handle, &sessionId, &keyNode, &pur, &alg);
962       if (ret != HKS_SUCCESS) {
963           HKS_LOG_E("GetParamsForCoreUpdate failed");
964           return ret;
965       }
966       //校验密钥参数
967       ret = HksCoreSecureAccessVerifyParams(keyNode, paramSet);
968       if (ret != HKS_SUCCESS) {
969           HksDeleteKeyNode(sessionId);
970           HKS_LOG_E("HksCoreFinish secure access verify failed");
971           return ret;
972       }
973       //调用对应的算法库密钥处理函数
974       uint32_t i;
975       uint32_t size = HKS_ARRAY_SIZE(g_hksCoreFinishHandler);
976       for (i = 0; i < size; i++) {
977           if (g_hksCoreFinishHandler[i].pur == pur) {
978               uint32_t outDataBufferSize = (outData == NULL) ? 0 : outData->size;
979               struct HuksBlob appendInData = { 0, NULL };
980               ret = HksCoreAppendAuthInfoBeforeFinish(keyNode, pur, paramSet, inData, &appendInData);
981               if (ret != HKS_SUCCESS) {
982                   HKS_LOG_E("before finish: append auth info failed");
983                   break;
984               }
985               ret = g_hksCoreFinishHandler[i].handler(keyNode, paramSet,
986                   appendInData.data == NULL ? inData : &appendInData, outData, alg);
987               if (appendInData.data != NULL) {
988                   HKS_FREE_BLOB(appendInData);
989               }
990               if (ret != HKS_SUCCESS) {
991                   break;
992               }
993               //添加密钥操作结束标签
994               ret = HksCoreAppendAuthInfoAfterFinish(keyNode, pur, paramSet, outDataBufferSize, outData);
995               break;
996           }
997       }
998       if (i == size) {
999           HKS_LOG_E("don't found purpose, pur : %d", pur);
1000           ret = HKS_FAILURE;
1001       }
1002       //删除对应的session
1003       HksDeleteKeyNode(sessionId);
1004       HKS_LOG_D("HksCoreFinish in Core end");
1005       return ret;
1006   }
1007   ```
1008
1009### 调测验证
1010
1011开发完成后,通过[HUKS JS接口](hhttps://gitee.com/openharmony/interface_sdk-js/blob/master/api/@ohos.security.huks.d.ts)开发JS应用来验证能力是否完备。
1012
1013对于每个HDI接口,[接口说明](#接口说明)都提供了对应的JS接口。可以通过调用JS接口组合来验证对应的HDI接口的能力,也可以通过完整的密钥操作来验证接口的能力。
1014
1015JS测试代码示例如下(仅供参考),如果整个流程能够正常运行,代表HDI接口能力正常。更多的密钥操作类型和完整样例请见[密钥管理服务](../../application-dev/security/UniversalKeystoreKit/huks-overview.md)。
1016
1017**AES生成密钥和加密**
1018
10191. 引入HUKS模块
1020
1021   ```ts
1022   import huks from '@ohos.security.huks'
1023   ```
1024
10252. 使用generateKey接口生成密钥。
1026
1027   ```ts
1028    import { BusinessError } from '@ohos.base';
1029    let aesKeyAlias = 'test_aesKeyAlias';
1030    let handle = 0;
1031    let IV = '001122334455';
1032
1033    class HuksProperties {
1034      tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM;
1035      value: huks.HuksKeyAlg | huks.HuksKeySize | huks.HuksKeyPurpose = huks.HuksKeyAlg.HUKS_ALG_ECC;
1036    }
1037
1038    class HuksProperties1 {
1039      tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM;
1040      value: huks.HuksKeyAlg | huks.HuksKeySize | huks.HuksKeyPurpose | huks.HuksKeyPadding | huks.HuksCipherMode | Uint8Array = huks.HuksKeyAlg.HUKS_ALG_ECC;
1041    }
1042
1043    function GetAesGenerateProperties() {
1044      let properties: HuksProperties[] = [
1045        {
1046          tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1047          value: huks.HuksKeyAlg.HUKS_ALG_AES
1048        },
1049        {
1050          tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1051          value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128
1052        },
1053        {
1054          tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1055          value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
1056          huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
1057        }
1058      ];
1059      return properties;
1060    }
1061
1062    async function GenerateAesKey() {
1063      let genProperties = GetAesGenerateProperties();
1064      let options: huks.HuksOptions = {
1065        properties: genProperties
1066      }
1067      await huks.generateKeyItem(aesKeyAlias, options).then((data) => {
1068        console.info("generateKeyItem success");
1069      }).catch((error: BusinessError) => {
1070        console.error("generateKeyItem failed");
1071      })
1072    }
1073   ```
1074
10753. 使用huks.initSessionhuks.finishSession进行加密。
1076
1077   ```ts
1078    let plainText = '123456';
1079
1080    function StringToUint8Array(str: string) {
1081      let arr: number[] = [];
1082      for (let i = 0, j = str.length; i < j; ++i) {
1083        arr.push(str.charCodeAt(i));
1084      }
1085      return new Uint8Array(arr);
1086    }
1087
1088    function GetAesEncryptProperties() {
1089      let properties: HuksProperties1[] = [
1090        {
1091          tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1092          value: huks.HuksKeyAlg.HUKS_ALG_AES
1093        },
1094        {
1095          tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1096          value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128
1097        },
1098        {
1099          tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1100          value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT
1101        },
1102        {
1103          tag: huks.HuksTag.HUKS_TAG_PADDING,
1104          value: huks.HuksKeyPadding.HUKS_PADDING_PKCS7
1105        },
1106        {
1107          tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
1108          value: huks.HuksCipherMode.HUKS_MODE_CBC
1109        },
1110        {
1111          tag: huks.HuksTag.HUKS_TAG_IV,
1112          value: StringToUint8Array(IV)
1113        }
1114      ]
1115      return properties;
1116    }
1117
1118    async function EncryptData() {
1119      let encryptProperties = GetAesEncryptProperties();
1120      let options: huks.HuksOptions = {
1121        properties: encryptProperties,
1122        inData: StringToUint8Array(plainText)
1123      }
1124      await huks.initSession(aesKeyAlias, options).then((data) => {
1125        handle = data.handle;
1126      }).catch((error: BusinessError) => {
1127        console.error("initSession failed");
1128      })
1129      await huks.finishSession(handle, options).then((data) => {
1130        console.info("finishSession success");
1131      }).catch((error: BusinessError) => {
1132        console.error("finishSession failed");
1133      })
1134    }
1135
1136   ```