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/huks-appendix.md#密钥材料格式)。
68
69- **证书链格式**
70
71  AttestKey返回的证书链应该按照业务证书、设备证书、CA证书和根证书的顺序组装,在每项证书之前还需要加上证书的长度。证书链组装完成后添加整个证书链的长度组装成Blob格式。证书的具体格式如要自己实现应与服务器侧解析的格式相对应。
72
73  ![CertChain格式图](figures/HUKS-CertChain.png)
74
75- **KeyBlob格式**
76  接口返回的密钥必须按照密钥存储态组装成KeyBlob,哪些接口需要遵循该限制请见[接口说明](#接口说明)。
77
78  ![KeyBlob格式图](figures/HUKS-KeyBlob.png)
79
80## 开发指导
81
82### 场景介绍
83
84HUKS Core作为向应用提供密钥库能力的基础,包括密钥管理及密钥的密码学操作等功能。如果想要使用自己的实现替换HUKS Core,需要实现以下接口。
85
86### 接口说明
87
88**表1** 接口功能介绍
89
90| 接口名                                                       | 功能介绍                                  | 约束与限制                     | 对应的js接口                                        |
91| ------------------------------------------------------------ | ---------------------------------------- | ----------------------------- | ------------------------------------------------------------ |
92| [ModuleInit()](#moduleinit)                   | HUKS Core的初始化。                            |  无                           | 无 |
93| [ModuleDestroy()](#moduledestroy)                   | HUKS Core的销毁。                            |  无                           | 无 |无                            | 无 |
94| [GenerateKey()](#generatekey)                  | 根据密码算法参数,生成密钥,并返回密文材料。                                |  出参要遵循KeyBlob格式          |generateKey(keyAlias: string, options: HuksOptions)|
95| [ImportKey()](#importkey)                     | 导入明文密钥,并返回密文材料。                            |  出参要遵循KeyBlob格式           | importKey(keyAlias: string, options: HuksOptions)|
96| [ImportWrappedKey()](#importwrappedkey)        |导入加密密钥,并返回密文材料。                              |  出参要遵循KeyBlob格式          | importWrappedKey(keyAlias: string, wrappingKeyAlias: string, options: HuksOptions)|
97| [ExportPublicKey()](#exportpublickey)         | 导出密钥对中的公钥。                                 |无                             | exportKey(keyAlias: string, options: HuksOptions) |
98| [Init()](#init)                              | 初始化密钥会话的接口,返回密钥会话句柄和令牌(可选)。                       |无                              | init(keyAlias: string, options: HuksOptions) |
99| [Update()](#update)                           | 追加密钥操作数据。                     |签名验签时入参是原始数据          | update(handle: number, token?: Uint8Array, options: HuksOptions) |
100| [Finish()](#finish)                           | 结束密钥会话                     |签名验签时入参是签名后数据        | finish(handle: number, options: HuksOptions) |
101| [Abort()](#abort)                         | 取消密钥会话                               |无                             | abort(handle: number, options: HuksOptions) |
102| [CheckKeyValidity()](#checkkeyvalidity)        | 校验密钥材料(密文)的完整性                              |无                            | 无 |
103| [AttestKey()](#attestkey)        | 获取密钥证书。                              |出参要遵循密钥证书链格式                      | attestKey(keyAlias: string, options: HuksOptions)|
104| [ExportChipsetPlatformPublicKey()](#exportchipsetplatformpublickey)        | 导出芯片平台级密钥对的公钥。     | 出参为ECC P256的x y轴值裸数据,各32字节                      | 无 |
105| [UpgradeKey()](#upgradekey)        | 升级密钥文件。     | 无                      | 无 |
106| [GenerateRandom()](#generaterandom)        | 生成安全随机数     | 无                      | 无 |
107| [Encrypt()](#encrypt)        | 加密     | 无                      | 无 |
108| [Decrypt()](#decrypt)        | 解密     | 无                      | 无 |
109| [Sign()](#sign)        | 签名     | 无                      | 无 |
110| [Verify()](#verify)        | 验签     | 无                      | 无 |
111| [AgreeKey()](#agreekey)        | 密钥协商     | 无                      | 无 |
112| [DeriveKey()](#derivekey)        | 密钥派生     | 无                      | 无 |
113| [Mac()](#mac)        | 消息认证码     | 无                      | 无 |
114
115- - -
116
117#### ModuleInit
118
119**接口描述**
120
121HUKS Core的初始化,一般用于初始化全局变量,比如全局线程锁,算法库,用于访问控制的AuthToken Key和根密钥。
122
123**接口原型**
124<pre><code>int32_t ModuleInit(struct IHuks *self);</code></pre>
125
126<details>
127  <summary><strong>参数说明</strong></summary>
128  <pre>
129  <strong>struct IHuks *self</strong>
130  HUKS HDI函数指针结构体指针
131  </pre>
132</details>
133
134<details>
135  <summary><strong>返回值</strong></summary>
136
137  - HKS_SUCCESS:成功,值为0,下同
138
139  - 其他:失败,值为负数,具体参考<a href="https://gitee.com/openharmony/security_huks/blob/master/interfaces/inner_api/huks_standard/main/include/hks_type.h">HksErrorCode枚举值定义</a>,下同
140</details>
141
142- - -
143
144
145#### ModuleDestroy
146
147**接口描述**
148
149HUKS Core的销毁,一般用于释放全局变量,包括锁,销毁内存中的AuthToken Key和根密钥等。
150
151**接口原型**
152<pre><code>int32_t ModuleDestroy(struct IHuks *self);</code></pre>
153
154<details>
155  <summary><strong>参数说明</strong></summary>
156  <pre>
157  <strong>struct IHuks *self</strong>
158  HUKS HDI函数指针结构体指针
159  </pre>
160</details>
161
162<details>
163  <summary><strong>返回值</strong></summary>
164
165  - HKS_SUCCESS:成功
166
167  - 其他:失败
168</details>
169
170- - -
171
172#### GenerateKey
173
174**接口描述**
175
176根据密钥属性paramSet生成密钥。
177
178**接口原型**
179<pre><code>int32_t GenerateKey(struct IHuks *self, const struct HuksBlob *keyAlias, const struct HuksParamSet *paramSet,
180    const struct HuksBlob *keyIn, struct HuksBlob *encKeyOut);</code></pre>
181
182<details>
183  <summary><strong>参数说明</strong></summary>
184  <pre>
185  <strong>struct IHuks *self</strong>
186  HUKS HDI函数指针结构体指针
187  <br></br>
188  <strong>const struct HuksBlob *keyAlias</strong>
189  将要生成的密钥的别名,要求:
190  1. keyAlias != null
191  2. keyAlias -> data != null
192  3. keyAlias -> dataLen != 0
193  <br></br>
194  <strong>const struct HuksParamSet *paramSet</strong>
195  要生成密钥的参数
196  <br></br>
197  <strong>const struct HuksBlob *keyIn</strong>
198  可选,通过密钥协商或密钥派生生成密钥时,传原密钥材料
199  <br></br>
200  <strong>struct HuksBlob *encKeyOut</strong>
201  出参,密钥密文材料,将密钥属性paramset和生成的密钥密文存放在这里,格式参考KeyBlob
202  </pre>
203</details>
204<br></br>
205
206<details>
207  <summary><strong>约束与限制</strong></summary>
208
209  1. 请在接口内检查上述参数是否符合要求,如是否是空指针、密钥算法是否支持等。
210
211  2. keyOut请参照KeyBlob的结构。
212
213</details>
214<br></br>
215
216<details>
217  <summary><strong>返回值</strong></summary>
218
219  - HKS_SUCCESS:成功
220
221  - 其他:失败
222</details>
223
224- - -
225
226#### ImportKey
227
228**接口描述**
229
230导入明文密钥。
231
232**接口原型**
233<pre><code>int32_t ImportKey(struct IHuks *self, const struct HuksBlob *keyAlias, const struct HuksBlob *key,
234    const struct HuksParamSet *paramSet, struct HuksBlob *encKeyOut);</code></pre>
235
236<details>
237  <summary><strong>参数说明</strong></summary>
238  <pre>
239  <strong>struct IHuks *self</strong>
240  HUKS HDI函数指针结构体指针
241  <br></br>
242  <strong>const struct HuksBlob *keyAlias</strong>
243  待导入的密钥的别名,要求:
244  1. keyAlias != null
245  2. keyAlias -> data != null
246  3. keyAlias -> dataLen != 0
247  <br></br>
248  <strong>const struct HuksBlob *key</strong>
249  待导入的密钥明文材料,密钥材料格式见<a href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/huks-appendix.md#%E5%AF%86%E9%92%A5%E6%9D%90%E6%96%99%E6%A0%BC%E5%BC%8F">密钥材料格式</a>,要求:
250  1. key != null
251  2. key -> data != null
252  3. key -> dataLen != 0
253  <br></br>
254  <strong>const struct HuksParamSet *paramSet</strong>
255  待导入密钥的参数
256  <br></br>
257  <strong>struct HuksBlob *encKeyOut</strong>
258  出参,密钥密文材料,将密钥属性paramset和生成的密钥密文存放在这里,格式参考KeyBlob
259  </pre>
260</details>
261<br></br>
262
263<details>
264  <summary><strong>约束与限制</strong></summary>
265
266  1. 请在接口内检查上述参数是否符合要求,如是否是空指针、密钥算法是否支持等。
267
268  2. encKeyOut请参照KeyBlob的结构。
269
270</details>
271<br></br>
272
273<details>
274  <summary><strong>返回值</strong></summary>
275
276  - HKS_SUCCESS:成功
277
278  - 其他:失败
279</details>
280
281- - -
282
283#### ImportWrappedKey
284
285**接口描述**
286
287导入加密密钥。
288
289**接口原型**
290<pre><code>int32_t ImportWrappedKey(struct IHuks *self, const struct HuksBlob *wrappingKeyAlias,
291    const struct HuksBlob *wrappingEncKey, const struct HuksBlob *wrappedKeyData, const struct HuksParamSet *paramSet,
292    struct HuksBlob *encKeyOut);</code></pre>
293
294<details>
295  <summary><strong>参数说明</strong></summary>
296  <pre>
297  <strong>struct IHuks *self</strong>
298  HUKS HDI函数指针结构体指针
299  <br></br>
300  <strong>const struct HuksBlob *wrappingKeyAlias</strong>
301  用于做加密导入的密钥的别名(非导入密钥本身的别名),要求:
302  1. wrappingKeyAlias != null
303  2. wrappingKeyAlias -> data != null
304  3. wrappingKeyAlias -> dataLen != 0
305  <br></br>
306  <strong>const struct HuksBlob *wrappingEncKey</strong>
307  要导入的密钥数据被加密时使用的密钥,要求:
308  1. wrappingEncKey != null
309  2. wrappingEncKey -> data != null
310  3. wrappingEncKey -> dataLen != 0
311  <br></br>
312  <strong>const struct HuksBlob *wrappedKeyData</strong>
313  要导入的密钥的密钥材料数据,格式参考<a href="https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/huks-guidelines.md#%E5%8A%A0%E5%AF%86%E5%AF%BC%E5%85%A5">加密导入材料格式</a>,要求:
314  1. wrappedKeyData != null
315  2. wrappedKeyData -> data != null
316  3. wrappedKeyData -> dataLen != 0
317  <br></br>
318  <strong>const struct HuksParamSet *paramSet</strong>
319  待导入密钥的密钥属性
320  <br></br>
321  <strong>struct HuksBlob *encKeyOut</strong>
322  导入密钥的密文材料,参考KeyBlob格式
323  </pre>
324</details>
325<br></br>
326
327<details>
328  <summary><strong>约束与限制</strong></summary>
329
330  1. 请在接口内检查上述参数是否符合要求,如是否是空指针、密钥算法是否支持等。
331
332  2. encKeyOut请参照KeyBlob的结构。
333
334</details>
335<br></br>
336
337<details>
338  <summary><strong>返回值</strong></summary>
339
340  - HKS_SUCCESS:成功
341
342  - 其他:失败
343</details>
344
345- - -
346
347#### ExportPublicKey
348
349**接口描述**
350
351导出密钥对的公钥。
352
353**接口原型**
354<pre><code>int32_t ExportPublicKey(struct IHuks *self, const struct HuksBlob *encKey,
355    const struct HuksParamSet *paramSet, struct HuksBlob *keyOut);</code></pre>
356
357<details>
358  <summary><strong>参数说明</strong></summary>
359  <pre>
360  <strong>struct IHuks *self</strong>
361  HUKS HDI函数指针结构体指针
362  <br></br>
363  <strong>const struct HuksBlob *encKey</strong>
364  与要导出的公钥的密钥对材料,要求:
365  1. encKey != null
366  2. encKey -> data != null
367  3. encKey -> dataLen != 0
368  <br></br>
369  <strong>const struct HuksParamSet *paramSet</strong>
370  导出公钥的所需要的参数,默认为空
371  <br></br>
372  <strong>struct HuksBlob *keyOut</strong>
373  出参,存放导出的公钥
374  </pre>
375</details>
376<br></br>
377
378<details>
379  <summary><strong>返回值</strong></summary>
380
381  - HKS_SUCCESS:成功
382
383  - 其他:失败
384</details>
385
386- - -
387
388#### Init
389
390**接口描述**
391
392初始化密钥会话的接口,传入密钥材料密文,在HUKS Core进行解密,并生成密钥会话句柄和令牌(按需)
393
394**接口原型**
395<pre><code>int32_t Init(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet,
396    struct HuksBlob *handle, struct HuksBlob *token);</code></pre>
397
398<details>
399  <summary><strong>参数说明</strong></summary>
400  <pre>
401  <strong>struct IHuks *self</strong>
402  HUKS HDI函数指针结构体指针
403  <br></br>
404  <strong>const struct HuksBlob *encKey</strong>
405  待操作密钥的密文材料,要求:
406  1. encKey != null
407  2. encKey -> data != null
408  3. encKey -> dataLen != 0
409  <br></br>
410  <strong>const struct HuksParamSet *paramSet</strong>
411  初始化密钥会话的参数
412  <br></br>
413  <strong>struct HuksBlob *handle</strong>
414  出参,密钥会话的句柄,作为Update、Finish和Abort的入参,用于索引密钥会话
415  <br></br>
416  <strong>struct HuksBlob *token</strong>
417  出参,存放密钥访问控制的认证令牌(按需)
418  </pre>
419</details>
420<br></br>
421
422<details>
423  <summary><strong>约束与限制</strong></summary>
424
425  1. 密钥会话操作函数,业务配合Update、Finish、Abort使用
426
427</details>
428<br></br>
429
430<details>
431  <summary><strong>返回值</strong></summary>
432
433  - HKS_SUCCESS:成功
434
435  - 其他:失败
436</details>
437
438- - -
439
440#### Update
441
442**接口描述**
443
444追加密钥操作数据,如密码算法的要求需要对数据进行分段操作。
445
446**接口原型**
447<pre><code>int32_t Update(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet,
448    const struct HuksBlob *inData, struct HuksBlob *outData);</code></pre>
449
450<details>
451  <summary><strong>参数说明</strong></summary>
452  <pre>
453  <strong>struct IHuks *self</strong>
454  HUKS HDI函数指针结构体指针
455  <br></br>
456  <strong>const struct HuksBlob *handle</strong>
457  密钥会话的句柄
458  <br></br>
459  <strong> const struct HuksParamSet *paramSet</strong>
460  追加操作的参数
461  <br></br>
462  <strong> const struct HuksBlob *inData</strong>
463  追加操作的输入
464  <br></br>
465  <strong> struct HuksBlob *outData</strong>
466  追加操作的结果
467  </pre>
468</details>
469<br></br>
470
471<details>
472  <summary><strong>约束与限制</strong></summary>
473
474  1. 密钥会话操作函数,业务配合Init、Finish、Abort使用。
475
476  2. 在进行签名验签时inData要传入原文数据。
477
478</details>
479<br></br>
480
481<details>
482  <summary><strong>返回值</strong></summary>
483
484  - HKS_SUCCESS:成功
485
486  - 其他:失败
487</details>
488
489- - -
490
491#### Finish
492
493**接口描述**
494
495结束密钥会话,操作最后一段数据并结束密钥会话。
496
497**接口原型**
498<pre><code>int32_t Finish(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet,
499    const struct HuksBlob *inData, struct HuksBlob *outData);</code></pre>
500
501<details>
502  <summary><strong>参数说明</strong></summary>
503  <pre>
504  <strong>struct IHuks *self</strong>
505  HUKS HDI函数指针结构体指针
506  <br></br>
507  <strong>const struct HuksBlob *handle</strong>
508  密钥会话的句柄
509  <br></br>
510  <strong>const struct HuksParamSet *paramSet</strong>
511  最后一段操作的参数
512  <br></br>
513  <strong>const struct HuksBlob *inData</strong>
514  最后一段操作的输入
515  <br></br>
516  <strong>struct HuksBlob *outData</strong>
517  密钥操作的结果
518  </pre>
519</details>
520<br></br>
521
522<details>
523  <summary><strong>约束与限制</strong></summary>
524
525  1. 密钥会话操作函数,业务配合Init、Update、Abort使用。
526
527  2. 在进行验签时inData要传入需要验证的签名数据,通过返回结果表示验签是否成功。
528
529</details>
530<br></br>
531
532<details>
533  <summary><strong>返回值</strong></summary>
534
535  - HKS_SUCCESS:成功
536
537  - 其他:失败
538</details>
539
540- - -
541
542#### Abort
543
544**接口描述**
545
546取消密钥会话。当Init,Update和Finish操作中的任一阶段发生错误时,都要调用abort来终止密钥会话。
547
548**接口原型**
549<pre><code>int32_t Abort(struct IHuks *self, const struct HuksBlob *handle, const struct HuksParamSet *paramSet);</code></pre>
550
551<details>
552  <summary><strong>参数说明</strong></summary>
553  <pre>
554  <strong>struct IHuks *self</strong>
555  HUKS HDI函数指针结构体指针
556  <br></br>
557  <strong>const struct HuksBlob *handle</strong>
558  密钥会话的句柄
559  <br></br>
560  <strong>const struct HuksParamSet *paramSet</strong>
561  Abort操作的参数
562  </pre>
563</details>
564<br></br>
565
566<details>
567  <summary><strong>约束与限制</strong></summary>
568
569  1. 密钥会话操作函数,业务配合Init、Update、Finish使用。
570
571</details>
572<br></br>
573
574<details>
575  <summary><strong>返回值</strong></summary>
576
577  - HKS_SUCCESS:成功
578
579  - 其他:失败
580</details>
581
582- - -
583
584#### CheckKeyValidity
585
586**接口描述**
587
588获取密钥属性。
589
590**接口原型**
591<pre><code>int32_t CheckKeyValidity(struct IHuks *self, const struct HuksParamSet *paramSet,
592    const struct HuksBlob *encKey);</code></pre>
593
594<details>
595  <summary><strong>参数说明</strong></summary>
596  <pre>
597  <strong>struct IHuks *self</strong>
598  HUKS HDI函数指针结构体指针
599  <br></br>
600  <strong>const struct HuksParamSet *paramSet</strong>
601  用于校验密钥完整性接口的参数,默认传空
602  <br></br>
603  <strong>const struct HuksBlob *encKey</strong>
604  待校验密钥完整性的密钥材料(密文)
605  </pre>
606</details>
607<br></br>
608
609<details>
610  <summary><strong>返回值</strong></summary>
611
612  - HKS_SUCCESS:成功
613
614  - 其他:失败
615</details>
616
617- - -
618
619#### AttestKey
620
621**接口描述**
622
623获取密钥证书。
624
625**接口原型**
626<pre><code>int32_t AttestKey(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet,
627    struct HuksBlob *certChain);</code></pre>
628
629<details>
630  <summary><strong>参数说明</strong></summary>
631  <pre>
632  <strong>struct IHuks *self</strong>
633  HUKS HDI函数指针结构体指针
634  <br></br>
635  <strong>const struct HuksBlob *encKey</strong>
636  要获取证书的密钥对材料密文
637  <br></br>
638  <strong>const struct HuksParamSet *paramSet</strong>
639  获取密钥证书操作的参数,如challenge等
640  <br></br>
641  <strong>struct HuksBlob *certChain</strong>
642  出参,存放证书链,格式参考上述证书链格式
643  </pre>
644</details>
645<br></br>
646
647<details>
648  <summary><strong>约束与限制</strong></summary>
649
650  1. certChain的格式需遵循[约束与限制第二点](#约束与限制)。
651
652</details>
653<br></br>
654
655<details>
656  <summary><strong>返回值</strong></summary>
657
658  - HKS_SUCCESS:成功
659
660  - 其他:失败
661</details>
662
663- - -
664
665#### ExportChipsetPlatformPublicKey
666
667**接口描述**
668
669导出芯片平台级密钥对的公钥。
670
671**接口原型**
672<pre><code>int32_t ExportChipsetPlatformPublicKey(struct IHuks *self, const struct HuksBlob *salt,
673    enum HuksChipsetPlatformDecryptScene scene, struct HuksBlob *publicKey);</code></pre>
674
675<details>
676  <summary><strong>参数说明</strong></summary>
677  <pre>
678  <strong>struct IHuks *self</strong>
679  HUKS HDI函数指针结构体指针
680  <br></br>
681  <strong>const struct HuksBlob *salt</strong>
682  用来派生芯片平台密钥对时的派生因子
683  <br></br>
684  <strong>enum HuksChipsetPlatformDecryptScene scene</strong>
685  业务预期进行芯片平台解密的场景
686  <br></br>
687  <strong>struct HuksBlob *publicKey</strong>
688  出参为ECC P256的x y轴值裸数据,各32字节
689  </pre>
690</details>
691<br></br>
692
693<details>
694  <summary><strong>约束与限制</strong></summary>
695
696  1. 入参`salt`长度必须为16字节,且最后一个字节的内容会被忽略,将由huks内部根据入参`scene`进行修改填充。<br>
697  当前huks的芯片平台级密钥对为软实现,硬编码了一对ECC-P256密钥对到代码中,`salt`值被忽略,即无论传入什么`salt`,派生出的密钥都是一样的。在真正基于硬件的芯片平台级密钥实现中,`salt`为用来派生密钥的派生因子,传入不同的`salt`会得到不同的密钥对。
698
699</details>
700<br></br>
701
702<details>
703  <summary><strong>返回值</strong></summary>
704
705  - HKS_SUCCESS:成功
706
707  - 其他:失败
708</details>
709
710- - -
711
712#### UpgradeKey
713
714**接口描述**
715
716升级密钥文件。当密钥文件版本号小于最新版本号时,触发该升级能力。
717
718**接口原型**
719<pre><code>int32_t UpgradeKey(struct IHuks *self, const struct HuksBlob *encOldKey, const struct HuksParamSet *paramSet,
720    struct HuksBlob *encNewKey);</code></pre>
721
722<details>
723  <summary><strong>参数说明</strong></summary>
724  <pre>
725  <strong>struct IHuks *self</strong>
726  HUKS HDI函数指针结构体指针
727  <br></br>
728  <strong>const struct HuksBlob *encOldKey</strong>
729  待升级的密钥文件数据
730  <br></br>
731  <strong>const struct HuksParamSet *paramSet</strong>
732  升级密钥文件数据的参数
733  <br></br>
734  <strong>struct HuksBlob *newKey</strong>
735  出参,升级后的密钥文件数据
736  </pre>
737</details>
738<br></br>
739
740<details>
741  <summary><strong>返回值</strong></summary>
742
743  - HKS_SUCCESS:成功
744
745  - 其他:失败
746</details>
747
748- - -
749
750#### GenerateRandom
751
752**接口描述**
753
754生成安全随机数
755
756**接口原型**
757<pre><code>int32_t GenerateRandom(struct IHuks *self, const struct HuksParamSet *paramSet, struct HuksBlob *random);</code></pre>
758
759<details>
760  <summary><strong>参数说明</strong></summary>
761  <pre>
762  <strong>struct IHuks *self</strong>
763  HUKS HDI函数指针结构体指针
764  <br></br>
765  <strong>const struct HuksParamSet *paramSet</strong>
766  待生成安全随机数的参数,如长度
767  <br></br>
768  <strong>struct HuksBlob *random</strong>
769  出参,随机数
770  </pre>
771</details>
772<br></br>
773
774<details>
775  <summary><strong>返回值</strong></summary>
776
777  - HKS_SUCCESS:成功
778
779  - 其他:失败
780</details>
781
782- - -
783
784#### Sign
785
786**接口描述**
787
788对数据进行签名
789
790**接口原型**
791<pre><code>int32_t Sign(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet,
792    const struct HuksBlob *srcData, struct HuksBlob *signature);</code></pre>
793
794<details>
795  <summary><strong>参数说明</strong></summary>
796  <pre>
797  <strong>struct IHuks *self</strong>
798  HUKS HDI函数指针结构体指针
799  <br></br>
800  <strong>const struct HuksBlob *encKey</strong>
801  用于签名的密钥对材料(密文)
802  <br></br>
803  <strong>const struct HuksParamSet *paramSet</strong>
804  用于签名的参数,如摘要模式
805  <br></br>
806  <strong>const struct HuksBlob *srcData</strong>
807  用于签名的数据
808  <br></br>
809  <strong>struct HuksBlob *signature</strong>
810  出参,数据签名
811  </pre>
812</details>
813<br></br>
814
815<details>
816  <summary><strong>返回值</strong></summary>
817
818  - HKS_SUCCESS:成功
819
820  - 其他:失败
821</details>
822
823- - -
824
825#### Verify
826
827**接口描述**
828
829对数据签名进行验签
830
831**接口原型**
832<pre><code>int32_t Verify(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet,
833    const struct HuksBlob *srcData, const struct HuksBlob *signature);</code></pre>
834
835<details>
836  <summary><strong>参数说明</strong></summary>
837  <pre>
838  <strong>struct IHuks *self</strong>
839  HUKS HDI函数指针结构体指针
840  <br></br>
841  <strong>const struct HuksBlob *encKey</strong>
842  用于验签的密钥对材料(密文)
843  <br></br>
844  <strong>const struct HuksParamSet *paramSet</strong>
845  用于验签的参数,如摘要模式
846  <br></br>
847  <strong>const struct HuksBlob *srcData</strong>
848  待验签的数据
849  <br></br>
850  <strong>const struct HuksBlob *signature</strong>
851  用于验签的签名
852  </pre>
853</details>
854<br></br>
855
856<details>
857  <summary><strong>返回值</strong></summary>
858
859  - HKS_SUCCESS:成功
860
861  - 其他:失败
862</details>
863
864- - -
865
866#### Encrypt
867
868**接口描述**
869
870对数据进行单次加密,相比密钥会话接口,该接口需满足一次调用即可完成加密操作
871
872**接口原型**
873<pre><code>int32_t Encrypt(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet,
874     const struct HuksBlob *plainText, struct HuksBlob *cipherText);</code></pre>
875
876<details>
877  <summary><strong>参数说明</strong></summary>
878  <pre>
879  <strong>struct IHuks *self</strong>
880  HUKS HDI函数指针结构体指针
881  <br></br>
882  <strong>const struct HuksBlob *encKey</strong>
883  用于加密的密钥材料(密文)
884  <br></br>
885  <strong>const struct HuksParamSet *paramSet</strong>
886  用于加密的密钥参数,如密钥工作模式、填充模式等
887  <br></br>
888  <strong>const struct HuksBlob *plainText</strong>
889  待加密的数据明文
890  <br></br>
891  <strong>const struct HuksBlob *cipherText</strong>
892  加密后的数据密文
893  </pre>
894</details>
895<br></br>
896
897<details>
898  <summary><strong>返回值</strong></summary>
899
900  - HKS_SUCCESS:成功
901
902  - 其他:失败
903</details>
904
905- - -
906
907#### Decrypt
908
909**接口描述**
910
911对数据进行单次解密,相比密钥会话接口,该接口需要满足一次调用完成解密操作
912
913**接口原型**
914<pre><code>int32_t Decrypt(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet,
915    const struct HuksBlob *cipherText, struct HuksBlob *plainText);</code></pre>
916
917<details>
918  <summary><strong>参数说明</strong></summary>
919  <pre>
920  <strong>struct IHuks *self</strong>
921  HUKS HDI函数指针结构体指针
922  <br></br>
923  <strong>const struct HuksBlob *encKey</strong>
924  用于解密的密钥材料(密文)
925  <br></br>
926  <strong>const struct HuksParamSet *paramSet</strong>
927  用于解密的密钥参数,如密钥工作模式、填充模式等
928  <br></br>
929  <strong>const struct HuksBlob *cipherText</strong>
930  待解密的数据密文
931  <br></br>
932  <strong>const struct HuksBlob *plainText</strong>
933  解密后的数据明文
934  </pre>
935</details>
936<br></br>
937
938<details>
939  <summary><strong>返回值</strong></summary>
940
941  - HKS_SUCCESS:成功
942
943  - 其他:失败
944</details>
945
946- - -
947
948#### AgreeKey
949
950**接口描述**
951
952对密钥进行协商,相比密钥会话接口,该接口需要满足一次调用完成密钥协商操作
953
954**接口原型**
955<pre><code>int32_t AgreeKey(struct IHuks *self, const struct HuksParamSet *paramSet,
956    const struct HuksBlob *encPrivateKey, const struct HuksBlob *peerPublicKey, struct HuksBlob *agreedKey);</code></pre>
957
958<details>
959  <summary><strong>参数说明</strong></summary>
960  <pre>
961  <strong>struct IHuks *self</strong>
962  HUKS HDI函数指针结构体指针
963  <br></br>
964  <strong>const struct HuksParamSet *paramSet</strong>
965  用于协商的参数,如协商密钥的长度
966  <br></br>
967  <strong>const struct HuksBlob *encPrivateKey</strong>
968  用于协商的密钥对材料(密文)
969  <br></br>
970  <strong>const struct HuksBlob *peerPublicKey</strong>
971  用于协商密钥对公钥(明文)
972  <br></br>
973  <strong>struct HuksBlob *agreedKey</strong>
974  出参,协商出的密钥明文
975  </pre>
976</details>
977<br></br>
978
979<details>
980  <summary><strong>返回值</strong></summary>
981
982  - HKS_SUCCESS:成功
983
984  - 其他:失败
985</details>
986
987- - -
988
989#### DeriveKey
990
991**接口描述**
992
993对密钥进行派生,相比密钥会话接口,该接口需要满足一次调用完成密钥派生操作
994
995**接口原型**
996<pre><code>int32_t DeriveKey(struct IHuks *self, const struct HuksParamSet *paramSet, const struct HuksBlob *encKdfKey,
997     struct HuksBlob *derivedKey);</code></pre>
998
999<details>
1000  <summary><strong>参数说明</strong></summary>
1001  <pre>
1002  <strong>struct IHuks *self</strong>
1003  HUKS HDI函数指针结构体指针
1004  <br></br>
1005  <strong>const struct HuksParamSet *paramSet</strong>
1006  用于密钥派生的参数,如派生密钥的长度
1007  <br></br>
1008  <strong>const struct HuksBlob *encKdfKey</strong>
1009  用于派生的密钥材料(密文)
1010  <br></br>
1011  <strong>struct HuksBlob *derivedKey</strong>
1012  出参,派生出的密钥(明文)
1013  </pre>
1014</details>
1015<br></br>
1016
1017<details>
1018  <summary><strong>返回值</strong></summary>
1019
1020  - HKS_SUCCESS:成功
1021
1022  - 其他:失败
1023</details>
1024
1025- - -
1026
1027#### Mac
1028
1029**接口描述**
1030
1031根据密钥生成消息认证码
1032
1033**接口原型**
1034<pre><code>int32_t Mac(struct IHuks *self, const struct HuksBlob *encKey, const struct HuksParamSet *paramSet,
1035     const struct HuksBlob *srcData, struct HuksBlob *mac);</code></pre>
1036
1037<details>
1038  <summary><strong>参数说明</strong></summary>
1039  <pre>
1040  <strong>struct IHuks *self</strong>
1041  HUKS HDI函数指针结构体指针
1042  <br></br>
1043  <strong>const struct HuksBlob *encKey</strong>
1044  用于生成消息认证码的密钥材料(密文)
1045  <br></br>
1046  <strong>const struct HuksParamSet *paramSet</strong>
1047  用于生成消息认证码的参数
1048  <br></br>
1049  <strong>const struct HuksBlob *srcData</strong>
1050  消息数据
1051  <br></br>
1052  <strong>struct HuksBlob *mac</strong>
1053  出参,消息认证码
1054  </pre>
1055</details>
1056<br></br>
1057
1058<details>
1059  <summary><strong>返回值</strong></summary>
1060
1061  - HKS_SUCCESS:成功
1062
1063  - 其他:失败
1064</details>
1065
1066- - -
1067### 开发步骤
1068
1069#### 代码目录
1070
10711. HDI接口的适配在以下目录中:
1072
1073```undefined
1074//drivers_peripheral/huks
1075├── BUILD.gn # 编译脚本
1076├── hdi_service # 实现依赖,通过dloppen方式引用libhuks_engine_core_standard.z.so(软实现的HUKS Core,仅用于参考)
1077    ├── huks_sa_type.h # HUKS服务层的数据结构定义
1078    ├── huks_sa_hdi_struct.h # libhuks_engine_core_standard.z.so中函数指针结构体的定义
1079    ├── huks_hdi_template.h # HUKS服务层和HDI接口数据结构的转化适配
1080    ├── huks_hdi_service.c # HUKS直通式HDI服务层的接口实现
1081    └── huks_hdi_passthrough_adapter.c # HUKS直通式HDI服务层到软实现HUKS Core的适配层
1082└── test # HUKS HDI接口unittest和fuzztest
1083    ├── BUILD.gn # 编译脚本
1084    ├── fuzztest # fuzz测试
1085    └── unittest # 单元测试
1086```
1087
10882. HUKS Core软实现的代码在以下目录中:
1089
1090```undefined
1091//base/security/huks/services/huks_standard/huks_engine
1092├── BUILD.gn # 编译脚本
1093├── core_dependency # HUKS Core依赖
1094└── core # HUKS Core层的软实现
1095    ├── BUILD.gn # 编译脚本
1096    ├── include
1097    └── src
1098        ├── hks_core_interfaces.c # HDI到HUKS Core的适配层
1099        └── hks_core_service.c # HUKS Core详细实现
1100        └── ... #其他功能代码
1101```
1102**注意事项!!!**
1103
1104  <summary><strong>HUKS Core软实现中存在硬编码相关敏感数据,包括根密钥、访问控制用的AuthToken密钥、加密AuthToken用的密钥、证书相关等,如设备开发者使用了相关代码,一定要替换成自有实现</strong></summary>
1105
1106  - **根密钥**
1107
1108    用于加密HUKS业务密钥,一般由设备根密钥派生而来,HUKS Core软实现中硬编码在代码中,详细代码见<a href="https://gitee.com/openharmony/security_huks/blob/master/frameworks/huks_standard/main/crypto_engine/openssl/src/hks_openssl_get_main_key.c">hks_openssl_get_main_key.c</a>
1109
1110 - **访问控制用于对AuthToken做HMAC的密钥**
1111
1112   用于UserIAM对AuthToken进行HMAC,HUKS Core软实现中硬编码在代码中,值为"huks_default_user_auth_token_key",详细代码见<a href="https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/core/src/hks_keyblob.c">hks_keyblob.c</a>
1113
1114 - **访问控制用于对AuthToken敏感字段加密的密钥**
1115
1116   用于UserIAM对AuthToken敏感字段进行加密的密钥,HUKS Core软实现中硬编码在代码中,值为"huks_default_user_auth_token_key",详细代码见<a href="https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/core/src/hks_keyblob.c">hks_keyblob.c</a>
1117
1118  - **根证书、设备CA、设备证书**
1119
1120    用于密钥证明,一般由设备证书管理模块预置在硬件设备安全存储当中,HUKS Core软实现中硬编码在代码中,详细代码见<a href="https://gitee.com/openharmony/security_huks/blob/master/services/huks_standard/huks_engine/main/device_cert_manager/include/dcm_certs_and_key.h">dcm_certs_and_key.h</a>
1121
1122#### 适配样例
1123
1124下文以HUKS Core中的密钥会话Init\Update\Finish接口适配作为一个样例,介绍基本流程,仅供参考不可实际运行,实际可运行代码参考[HUKS源码目录](https://gitee.com/openharmony/security_huks)
1125
11261. 创建一个句柄,通过这个句柄在session中存储密钥操作相关的信息,使得外部可以通过这个句柄分多次进行同一密钥操作。
1127
1128   ```c
1129
1130   //密钥会话Init接口
1131
1132   int32_t HksCoreInit(const struct  HuksBlob *key, const struct HuksParamSet *paramSet, struct HuksBlob *handle,
1133    struct HuksBlob *token)
1134   {
1135       HKS_LOG_D("HksCoreInit in Core start");
1136       uint32_t pur = 0;
1137       uint32_t alg = 0;
1138       //检查参数
1139       if (key == NULL || paramSet == NULL || handle == NULL || token == NULL) {
1140           HKS_LOG_E("the pointer param entered is invalid");
1141           return HKS_FAILURE;
1142        }
1143
1144        if (handle->size < sizeof(uint64_t)) {
1145            HKS_LOG_E("handle size is too small, size : %u", handle->size);
1146            return HKS_ERROR_INSUFFICIENT_MEMORY;
1147        }
1148        //解密密钥文件
1149        struct HuksKeyNode *keyNode = HksCreateKeyNode(key, paramSet);
1150        if (keyNode == NULL || handle == NULL) {
1151            HKS_LOG_E("the pointer param entered is invalid");
1152            return HKS_ERROR_BAD_STATE;
1153        }
1154        //通过handle向session中存储信息,供Update/Finish使用。使得外部可以通过同个handle分多次进行同一密钥操作。
1155        handle->size = sizeof(uint64_t);
1156        (void)memcpy_s(handle->data, handle->size, &(keyNode->handle), handle->size);
1157        //从参数中提取出算法
1158        int32_t ret = GetPurposeAndAlgorithm(paramSet, &pur, &alg);
1159        if (ret != HKS_SUCCESS) {
1160            HksDeleteKeyNode(keyNode->handle);
1161            return ret;
1162        }
1163        //检查密钥参数
1164        ret = HksCoreSecureAccessInitParams(keyNode, paramSet, token);
1165        if (ret != HKS_SUCCESS) {
1166            HKS_LOG_E("init secure access params failed");
1167            HksDeleteKeyNode(keyNode->handle);
1168            return ret;
1169        }
1170        //通过密钥使用目的获取对应的算法库处理函数
1171        uint32_t i;
1172        uint32_t size = HKS_ARRAY_SIZE(g_hksCoreInitHandler);
1173        for (i = 0; i < size; i++) {
1174           if (g_hksCoreInitHandler[i].pur == pur) {
1175               HKS_LOG_E("Core HksCoreInit [pur] = %d, pur = %d", g_hksCoreInitHandler[i].pur, pur);
1176               ret = g_hksCoreInitHandler[i].handler(keyNode, paramSet, alg);
1177               break;
1178        }
1179        }
1180        //异常结果检查
1181        if (ret != HKS_SUCCESS) {
1182            HksDeleteKeyNode(keyNode->handle);
1183            HKS_LOG_E("CoreInit failed, ret : %d", ret);
1184            return ret;
1185        }
1186
1187        if (i == size) {
1188            HksDeleteKeyNode(keyNode->handle);
1189            HKS_LOG_E("don't found purpose, pur : %u", pur);
1190            return HKS_FAILURE;
1191        }
1192
1193        HKS_LOG_D("HksCoreInit in Core end");
1194        return ret;
1195    }
1196   ```
1197
11982. 在执行密钥操作前通过句柄获得上下文信息,执行密钥操作时放入分片数据并取回密钥操作结果或者追加数据。
1199
1200    ```c
1201    //密钥会话Update接口
1202    int32_t HksCoreUpdate(const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData,
1203        struct HuksBlob *outData)
1204    {
1205        HKS_LOG_D("HksCoreUpdate in Core start");
1206        uint32_t pur = 0;
1207        uint32_t alg = 0;
1208        //检查参数
1209        if (handle == NULL || paramSet == NULL || inData == NULL) {
1210            HKS_LOG_E("the pointer param entered is invalid");
1211            return HKS_FAILURE;
1212        }
1213
1214        uint64_t sessionId;
1215        struct HuksKeyNode *keyNode = NULL;
1216        //根据handle获取本次密钥会话操作需要的上下文
1217        int32_t ret = GetParamsForUpdateAndFinish(handle, &sessionId, &keyNode, &pur, &alg);
1218        if (ret != HKS_SUCCESS) {
1219            HKS_LOG_E("GetParamsForCoreUpdate failed");
1220            return ret;
1221        }
1222        //校验密钥参数
1223        ret = HksCoreSecureAccessVerifyParams(keyNode, paramSet);
1224        if (ret != HKS_SUCCESS) {
1225            HksDeleteKeyNode(sessionId);
1226            HKS_LOG_E("HksCoreUpdate secure access verify failed");
1227            return ret;
1228        }
1229        //调用对应的算法库密钥处理函数
1230        uint32_t i;
1231        uint32_t size = HKS_ARRAY_SIZE(g_hksCoreUpdateHandler);
1232        for (i = 0; i < size; i++) {
1233            if (g_hksCoreUpdateHandler[i].pur == pur) {
1234                struct HuksBlob appendInData = { 0, NULL };
1235                ret = HksCoreAppendAuthInfoBeforeUpdate(keyNode, pur, paramSet, inData, &appendInData);
1236                if (ret != HKS_SUCCESS) {
1237                    HKS_LOG_E("before update: append auth info failed");
1238                    break;
1239                }
1240                ret = g_hksCoreUpdateHandler[i].handler(keyNode, paramSet,
1241                     appendInData.data == NULL ? inData : &appendInData, outData, alg);
1242                if (appendInData.data != NULL) {
1243                    HKS_FREE_BLOB(appendInData);
1244                }
1245                break;
1246            }
1247        }
1248        //异常结果检查
1249        if (ret != HKS_SUCCESS) {
1250            HksDeleteKeyNode(keyNode->handle);
1251            HKS_LOG_E("CoreUpdate failed, ret : %d", ret);
1252            return ret;
1253        }
1254
1255        if (i == size) {
1256            HksDeleteKeyNode(sessionId);
1257            HKS_LOG_E("don't found purpose, pur : %u", pur);
1258            return HKS_FAILURE;
1259        }
1260        return ret;
1261    }
1262    ```
1263
12643. 结束密钥操作并取回结果,销毁句柄。
1265
1266   ```c
1267   //密钥会话Finish接口
1268   int32_t HksCoreFinish(const struct HuksBlob *handle, const struct HuksParamSet *paramSet, const struct HuksBlob *inData,
1269    struct HuksBlob *outData)
1270   {
1271       HKS_LOG_D("HksCoreFinish in Core start");
1272       uint32_t pur = 0;
1273       uint32_t alg = 0;
1274       //检查参数
1275       if (handle == NULL || paramSet == NULL || inData == NULL) {
1276           HKS_LOG_E("the pointer param entered is invalid");
1277           return HKS_FAILURE;
1278       }
1279
1280       uint64_t sessionId;
1281       struct HuksKeyNode *keyNode = NULL;
1282       //根据handle获取本次密钥会话操作需要的上下文
1283       int32_t ret = GetParamsForUpdateAndFinish(handle, &sessionId, &keyNode, &pur, &alg);
1284       if (ret != HKS_SUCCESS) {
1285           HKS_LOG_E("GetParamsForCoreUpdate failed");
1286           return ret;
1287       }
1288       //校验密钥参数
1289       ret = HksCoreSecureAccessVerifyParams(keyNode, paramSet);
1290       if (ret != HKS_SUCCESS) {
1291           HksDeleteKeyNode(sessionId);
1292           HKS_LOG_E("HksCoreFinish secure access verify failed");
1293           return ret;
1294       }
1295       //调用对应的算法库密钥处理函数
1296       uint32_t i;
1297       uint32_t size = HKS_ARRAY_SIZE(g_hksCoreFinishHandler);
1298       for (i = 0; i < size; i++) {
1299           if (g_hksCoreFinishHandler[i].pur == pur) {
1300               uint32_t outDataBufferSize = (outData == NULL) ? 0 : outData->size;
1301               struct HuksBlob appendInData = { 0, NULL };
1302               ret = HksCoreAppendAuthInfoBeforeFinish(keyNode, pur, paramSet, inData, &appendInData);
1303               if (ret != HKS_SUCCESS) {
1304                   HKS_LOG_E("before finish: append auth info failed");
1305                   break;
1306               }
1307               ret = g_hksCoreFinishHandler[i].handler(keyNode, paramSet,
1308                   appendInData.data == NULL ? inData : &appendInData, outData, alg);
1309               if (appendInData.data != NULL) {
1310                   HKS_FREE_BLOB(appendInData);
1311               }
1312               if (ret != HKS_SUCCESS) {
1313                   break;
1314               }
1315               //添加密钥操作结束标签
1316               ret = HksCoreAppendAuthInfoAfterFinish(keyNode, pur, paramSet, outDataBufferSize, outData);
1317               break;
1318           }
1319       }
1320       if (i == size) {
1321           HKS_LOG_E("don't found purpose, pur : %d", pur);
1322           ret = HKS_FAILURE;
1323       }
1324       //删除对应的session
1325       HksDeleteKeyNode(sessionId);
1326       HKS_LOG_D("HksCoreFinish in Core end");
1327       return ret;
1328   }
1329   ```
1330
1331### 调测验证
1332
1333开发完成后,通过[HUKS JS接口](https://gitee.com/openharmony/security_huks/blob/master/interfaces/kits/js/@ohos.security.huks.d.ts)开发JS应用来验证能力是否完备。
1334
1335对于每个HDI接口,[接口说明](#接口说明)都提供了对应的JS接口。可以通过调用JS接口组合来验证对应的HDI接口的能力,也可以通过完整的密钥操作来验证接口的能力。
1336
1337JS测试代码示例如下(仅供参考),如果整个流程能够正常运行,代表HDI接口能力正常。更多的密钥操作类型和完整样例请见[huks-guidelines.md](../../application-dev/security/huks-guidelines.md)。
1338
1339**AES生成密钥和加密**
1340
13411. 引入HUKS模块
1342
1343   ```ts
1344   import huks from '@ohos.security.huks'
1345   ```
1346
13472. 使用generateKey接口生成密钥。
1348
1349   ```ts
1350    import { BusinessError } from '@ohos.base';
1351    let aesKeyAlias = 'test_aesKeyAlias';
1352    let handle = 0;
1353    let IV = '001122334455';
1354
1355    class HuksProperties {
1356      tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM;
1357      value: huks.HuksKeyAlg | huks.HuksKeySize | huks.HuksKeyPurpose = huks.HuksKeyAlg.HUKS_ALG_ECC;
1358    }
1359
1360    class HuksProperties1 {
1361      tag: huks.HuksTag = huks.HuksTag.HUKS_TAG_ALGORITHM;
1362      value: huks.HuksKeyAlg | huks.HuksKeySize | huks.HuksKeyPurpose | huks.HuksKeyPadding | huks.HuksCipherMode | Uint8Array = huks.HuksKeyAlg.HUKS_ALG_ECC;
1363    }
1364
1365    function GetAesGenerateProperties() {
1366      let properties: HuksProperties[] = [
1367        {
1368          tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1369          value: huks.HuksKeyAlg.HUKS_ALG_AES
1370        },
1371        {
1372          tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1373          value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128
1374        },
1375        {
1376          tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1377          value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT |
1378          huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_DECRYPT
1379        }
1380      ];
1381      return properties;
1382    }
1383
1384    async function GenerateAesKey() {
1385      let genProperties = GetAesGenerateProperties();
1386      let options: huks.HuksOptions = {
1387        properties: genProperties
1388      }
1389      await huks.generateKeyItem(aesKeyAlias, options).then((data) => {
1390        console.log("generateKeyItem success");
1391      }).catch((error: BusinessError) => {
1392        console.log("generateKeyItem failed");
1393      })
1394    }
1395   ```
1396
13973. 使用huks.initSessionhuks.finishSession进行加密。
1398
1399   ```ts
1400    let plainText = '123456';
1401
1402    function StringToUint8Array(str: string) {
1403      let arr: number[] = [];
1404      for (let i = 0, j = str.length; i < j; ++i) {
1405        arr.push(str.charCodeAt(i));
1406      }
1407      return new Uint8Array(arr);
1408    }
1409
1410    function GetAesEncryptProperties() {
1411      let properties: HuksProperties1[] = [
1412        {
1413          tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
1414          value: huks.HuksKeyAlg.HUKS_ALG_AES
1415        },
1416        {
1417          tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
1418          value: huks.HuksKeySize.HUKS_AES_KEY_SIZE_128
1419        },
1420        {
1421          tag: huks.HuksTag.HUKS_TAG_PURPOSE,
1422          value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_ENCRYPT
1423        },
1424        {
1425          tag: huks.HuksTag.HUKS_TAG_PADDING,
1426          value: huks.HuksKeyPadding.HUKS_PADDING_PKCS7
1427        },
1428        {
1429          tag: huks.HuksTag.HUKS_TAG_BLOCK_MODE,
1430          value: huks.HuksCipherMode.HUKS_MODE_CBC
1431        },
1432        {
1433          tag: huks.HuksTag.HUKS_TAG_IV,
1434          value: StringToUint8Array(IV)
1435        }
1436      ]
1437      return properties;
1438    }
1439
1440    async function EncryptData() {
1441      let encryptProperties = GetAesEncryptProperties();
1442      let options: huks.HuksOptions = {
1443        properties: encryptProperties,
1444        inData: StringToUint8Array(plainText)
1445      }
1446      await huks.initSession(aesKeyAlias, options).then((data) => {
1447        handle = data.handle;
1448      }).catch((error: BusinessError) => {
1449        console.log("initSession failed");
1450      })
1451      await huks.finishSession(handle, options).then((data) => {
1452        console.log("finishSession success");
1453      }).catch((error: BusinessError) => {
1454        console.log("finishSession failed");
1455      })
1456    }
1457
1458   ```