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 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  74 75- **KeyBlob格式** 76 接口返回的密钥必须按照密钥存储态组装成KeyBlob,哪些接口需要遵循该限制请见[接口说明](#接口说明)。 77 78  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.initSession,huks.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 ```