CryptoExtensionAbility适配开发指导
============================

#### 适配指导

本文档旨在指导驱动厂商如何继承实现[CryptoExtensionAbility](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cryptoextensionability)需要的接口能力，此处给出实现参考，其他实现依照业务需要依次调用driver封装的底层驱动函数。

在DevEco Studio工程中手动新建一个CryptoExtensionAbility组件，具体步骤如下：

1.  在工程Module对应的ets目录下，右键选择“New > Directory”，新建一个目录，名称可以自己定义，例如cryptoability。
    
2.  在cryptoability目录，右键选择“New > ArkTS File”，新建一个文件，名称可以自己定义，例如CryptoAbility.ets。
    
    其目录结构如下所示：
    
    ├── ets
    │   └── cryptoability
    │       └── CryptoAbility.ets
    
3.  开发CryptoExtensionAbility需要配置[ohos.permission.CRYPTO\_EXTENSION\_REGISTER](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/restricted-permissions#ohospermissioncrypto_extension_register)权限，该权限属于[受限开放权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/restricted-permissions)，请按照[申请受限权限](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/declare-permissions-in-acl)指引为应用进行申请。
    
    // entry/src/main/module.json5
    {
      "module": {
        // ...
        "requestPermissions": \[
          {
            "name": "ohos.permission.CRYPTO\_EXTENSION\_REGISTER"
          }
        \],
      }
    }
    
4.  在工程Module对应的module.json5配置文件中注册AppServiceExtensionAbility组件，name标签表示ability名称，长度最大为127字节，srcEntry标签表示当前CryptoExtensionAbility组件所对应的代码路径，type标签需要设置为“crypto”，exported标签设置为false表示不允许三方应用调用，配置多个ability时要求每个name标签必须是唯一的。
    
    // entry/src/main/module.json5
    {
      "module": {
        // ...
        "extensionAbilities": \[
            {
              "name": "CryptoExtension",
              "srcEntry": "./ets/cryptoability/CryptoAbility.ets",
              "type": "crypto",
              "exported": false
            }
        \],
      }
    }
    
5.  在CryptoAbility.ets文件中，增加导入CryptoExtensionAbility的依赖包，自定义类继承CryptoExtensionAbility组件并实现其中的接口函数。导入CryptoExtensionAbility需要实现在[CryptoExtensionAbility](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cryptoextensionability)中给出的所有函数，此处给出实现参考，与底层驱动的调用对应关系见下文。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f1/v3/3asb3joHSeqbgnLQjgjnsg/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132429Z&HW-CC-Expire=86400&HW-CC-Sign=1D9A19FA516B1D42AA9DB74DC72AC3BB3CC831A00225BC5A95EF551235A1220F)
    
    1.  句柄资源和PIN认证状态需要做基于UID的隔离，在onOpenResource、onCloseResource、onAuthUkeyPin、onGetUkeyPinAuthState和onClearUkeyPinAuthState接口的入参params中会包含业务的UID信息（通过[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)可获取业务身份），可基于此做句柄资源和PIN认证状态的隔离。
    2.  接口函数的错误不支持自定义返回，不按接口定义方式返回会导致异常。
    
    import { huks, huksExternalCrypto, CryptoExtensionAbility, HuksCryptoExtensionCertInfo, HuksCryptoExtensionResult } from '@kit.UniversalKeystoreKit';
    import { util } from '@kit.ArkTS'
    import { cryptoFramework } from '@kit.CryptoArchitectureKit'
    
    class CryptoExtension extends CryptoExtensionAbility {
      // 本步骤内的接口函数实现均需在class内，为方便开发者理解及使用，每个接口函数在下文详细解释。
    }
    
    **接口介绍：**
    
    （1）onOpenResource在Ukey签名验签操作中用于打开指定资源（如建立会话或连接）。resourceId表示要打开的资源标识，应用身份可以在params中由[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带。当调用成功时，返回值中的resultCode成员设置为0，handle成员非空；调用失败时，resultCode携带错误码信息。
    
    onOpenResource(resourceId: string, params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      // 构造结果对象，默认返回操作失败，返回值为HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
    
      // 获取 appId
      let appId: string | undefined = params.find((param =>
        param.tag === huksExternalCrypto.HuksExternalCryptoTag.HUKS\_EXT\_CRYPTO\_TAG\_UID))?.value.toString();
      if (appId === undefined) {
        return Promise.resolve(result);
      }
    
      // 解析 resource index
      let index: string = JSON.parse(resourceId)\['index'\];
    
      // ...
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onOpenResource(index, ...);
        // 场景：打开资源成功
        result.resultCode = res.resultCode
        result.handle = res.handle
      } catch (error) {
        // 场景：打开资源失败
        result.resultCode = res.resultCode
        console.error(\`promise: onOpenResource failed\`);
      }
      return Promise.resolve(result);
    }
    
    （2）onCloseResource在Ukey签名验签操作中用于关闭指定资源（如释放会话或连接）。handle为待关闭资源的句柄，应用身份可以在params中由[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带。当调用成功时，返回值中的resultCode成员设置为0；调用失败时，resultCode携带错误码信息。
    
    onCloseResource(handle: string, params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      // ...
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
      
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_closeOpenResource(handle, ...);
        // 场景：关闭资源成功
        result.resultCode = res.resultCode
      } catch (error) {
        // 场景：关闭资源失败
        result.resultCode = res.resultCode
        console.error(\`promise: onCloseResource failed\`);
      }
      return Promise.resolve(result);
    }
    
    （3）onGetProperty在Ukey签名验签操作中用于获取指定资源的属性信息。handle为资源句柄，propertyId为待获取的属性标识，应用身份可以在params中由[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带。当调用成功时，返回值中的resultCode成员设置为0，返回值中的property成员包含属性信息。调用失败时，resultCode携带错误码信息。
    
    在onGetProperty中须实现导出公钥功能，以便上游业务使用PIN加密传输并完成PIN码认证。加密算法支持RSA、SM2等。当入参propertyId为SKF\_ExportPublicKey时，返回的公钥信息采用JSON格式，包含以下4个必选字段，分别是publicKey（公钥数据）、algo（算法类型及密钥长度）、transformation（密码学操作参数，如填充模式）、size（公钥数据长度）。具体实现可参考下方示例代码中onGetProperty接口的相关部分。
    
    onGetProperty(handle: string, propertyId: string, params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      // ...
      let emptyArray: Array<huksExternalCrypto.HuksExternalCryptoParam> = \[\];
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        property: emptyArray
      };
    
      // 导出公钥
      if (propertyId == 'SKF\_ExportPublicKey') {
        result.resultCode = 0
        let encryptionAlgo: string = 'RSA1024'
        let padding: string = 'PRIMES\_2';
        // 1. 创建一个AsyKeyGenerator实例。
        let rsaGenerator = cryptoFramework.createAsyKeyGenerator(\`${encryptionAlgo}|${padding}\`);
        // 2. 使用密钥生成器随机生成非对称密钥对。
        let keyPair = rsaGenerator.generateKeyPairSync();
        // 3. 将公钥导出，并转换为Json字符串
        const pkData = Array.from(keyPair.pubKey.getEncoded().data);
        let transformation: string = 'RSA1024|PKCS1'
        const encoder = new util.TextEncoder();
        let info = encoder.encodeInto(JSON.stringify({
          publicKey: pkData,
          algo: encryptionAlgo,
          transformation: transformation,
          size: pkData.length
        }));
        // 4. 保存私钥，后续用于解密加密的数据
        let privKey = keyPair.priKey
        // 返回用来加密传pin的公钥和加密算法信息，详见导出公钥文档
        result.property = \[
          { tag: huksExternalCrypto.HuksExternalCryptoTag.HUKS\_EXT\_CRYPTO\_TAG\_EXTRA\_DATA, value: info }
        \]
        return Promise.resolve(result);
      }
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：获取属性成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onGetProperty(...);
        result.resultCode = res.resultCode
        result.property = res.property
      } catch (error) {
        // 场景：获取属性失败
        result.resultCode = res.resultCode
        console.error(\`promise: onGetProperty failed\`);
      }
      return Promise.resolve(result);
    }
    
    （4）onAuthUkeyPin用于在Ukey签名之前验证PIN码。加密后的PIN码通过param中传入[HUKS\_EXT\_CRYPTO\_TAG\_UKEY\_PIN](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带，需使用onGetProperty中保存的私钥进行解密。
    
    当PIN码校验成功时，返回值中的resultCode成员设置为0，返回值中的authState设置为[HUKS\_EXT\_CRYPTO\_PIN\_AUTH\_SUCCEEDED](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalpinauthstate)。当PIN码不正确时，resultCode携带错误码信息，返回值中的retryCount设置为剩余重试次数，每次认证失败重试次数减1，当重试次数为0时，resultCode设置为[HUKS\_CRYPTO\_EXTENSION\_ERR\_PIN\_LOCKED](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cryptoextensionability#hukscryptoextensionresultcode)，authState设置为[HUKS\_EXT\_CRYPTO\_PIN\_LOCKED](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalpinauthstate)。
    
    onAuthUkeyPin(handle: string, params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      let pin: string | undefined = undefined;
      for (let param of params) {
        if (param.tag == huksExternalCrypto.HuksExternalCryptoTag.HUKS\_EXT\_CRYPTO\_TAG\_UKEY\_PIN) {
          let originPinData = param.value as Uint8Array;
          // 根据导出公钥所传出的加密算法和填充方式进行解密originPinData获取pin
          // ...
        }
      }
      // ...
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        authState: huksExternalCrypto.HuksExternalPinAuthState.HUKS\_EXT\_CRYPTO\_PIN\_NO\_AUTH,
        retryCount: 0
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：PIN码认证成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onAuthUkeyPin(pin, ...);
        result.resultCode = res.resultCode
        result.authState = res.authState
      } catch (error) {
        // 场景：PIN码认证失败
        result.resultCode = res.resultCode
        result.retryCount = res.retryCount
        console.error(\`promise: onAuthUkeyPin failed\`);
      }
      return Promise.resolve(result);
    }
    
    （5）onGetUkeyPinAuthState用于应用查询PIN码的认证状态。当调用成功时，返回值中的resultCode成员设置为0，返回值中的authState设置为对应的认证状态。调用失败时，resultCode携带错误码信息。
    
    onGetUkeyPinAuthState(handle: string, params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      // ...
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        authState: 0
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：获取PIN码认证状态成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onAuthUkeyPin(...);
        result.resultCode = res.resultCode
        result.authState = res.authState
        if (result.authState != 0) {
          // 场景： PIN码已认证
          // ...
        } else {
          // 场景： PIN码未认证
          // ...
        }
      } catch (error) {
        // 场景：获取PIN码认证状态失败
        result.resultCode = res.resultCode
        console.error(\`promise: onGetUkeyPinAuthState failed\`);
      }
      return Promise.resolve(result);
    }
    
    （6）onClearUkeyPinAuthState用于重置PIN码的认证状态。当调用成功时，返回值中的resultCode成员设置为0。调用失败时，resultCode携带错误码信息。
    
    onClearUkeyPinAuthState(handle: string, params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      // ...
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：清除PIN码认证状态成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onClearUkeyPinAuthState(...);
        result.resultCode = res.resultCode
      } catch (error) {
        // 场景：清除PIN码认证状态失败
        result.resultCode = res.resultCode
        console.error(\`promise: onClearUkeyPinAuthState failed\`);
      }
      return Promise.resolve(result);
    }
    
    （7）onInitSession在Ukey签名验签操作中用于初始化密钥会话。应用身份可以在param中由[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带。当调用成功时，返回值中的resultCode成员设置为0，handle成员非空。调用失败时，resultCode携带错误码信息。
    
    onInitSession(handle: string, params: huks.HuksOptions): Promise<HuksCryptoExtensionResult> {
      // ...
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        handle: ""
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：三段式init阶段成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onInitSession(...);
        result.resultCode = res.resultCode
        result.handle = res.handle
      } catch (error) {
        // 场景：三段式init阶段失败
        result.resultCode = res.resultCode
        console.error(\`promise: onInitSession failed\`);
      }
      return Promise.resolve(result);
    }
    
    （8）onUpdateSession在Ukey签名验签操作中用于分段传输大批量数据。应用身份可以在param中由[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带。当调用成功时，返回值中的resultCode成员设置为0。调用失败时，resultCode携带错误码信息。
    
    onUpdateSession(handle: string, params: huks.HuksOptions): Promise<HuksCryptoExtensionResult> {
      // ...
      let certs: Uint8Array = new Uint8Array();
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        outData: certs
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：三段式update阶段成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onUpdateSession(...);
        result.resultCode = res.resultCode
        result.outData = res.outData
      } catch (error) {
        // 场景：三段式update阶段失败
        result.resultCode = res.resultCode
        console.error(\`promise: onUpdateSession failed\`);
      }
      return Promise.resolve(result);
    }
    
    （9）onFinishSession在Ukey签名操作中用于传输最后一段明文，在验签操作中用于传输签名。应用身份可以在param中由[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带。当调用成功时，返回值中的resultCode成员设置为0。调用失败时，resultCode携带错误码信息。
    
    onFinishSession(handle: string, params: huks.HuksOptions): Promise<HuksCryptoExtensionResult> {
      // ...
      let certs: Uint8Array = new Uint8Array();
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        outData: certs
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
      try {
        // 场景：三段式finish阶段成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onFinishSession(...);
        result.resultCode = res.resultCode
        result.outData = res.outData
      } catch (error) {
        // 场景：三段式finish阶段失败
        result.resultCode = res.resultCode
        console.error(\`promise: onFinishSession failed\`);
      }
      return Promise.resolve(result);
    }
    
    （10）onExportCertificate用于查询某个resourceId下的证书。可以通过解析参数[HUKS\_EXT\_CRYPTO\_TAG\_PURPOSE](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)获取业务希望的证书类型。如未指定，默认获取的证书类型是签名证书。
    
    其值含义如下：
    
    0：默认用途。
    
    1：用于查询所有凭据。
    
    2：用于凭据签名。
    
    3：用于凭据加密。
    
    onExportCertificate(resourceId: string, params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      // ...
      let certInfoSetArray: Array<HuksCryptoExtensionCertInfo> = \[\]
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        certs: certInfoSetArray
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：导出证书成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onExportCertificate(...);
        result.resultCode = res.resultCode
        result.certs = res.certs
      } catch (error) {
        // 场景：导出证书失败
        result.resultCode = res.resultCode
        console.error(\`promise: onExportCertificate failed\`);
      }
      return Promise.resolve(result);
    }
    
    （11）onEnumCertificates在Ukey签名验签操作中用于枚举证书列表。应用身份可以在params中由[HUKS\_EXT\_CRYPTO\_TAG\_UID](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)参数携带。当调用成功时，返回值中的resultCode成员设置为0，返回值中的certs成员包含证书列表（类型为Array<[HuksCryptoExtensionCertInfo](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-cryptoextensionability#hukscryptoextensioncertinfo)\>）。调用失败时，resultCode携带错误码信息。
    
    onEnumCertificates(params: Array<huksExternalCrypto.HuksExternalCryptoParam>): Promise<HuksCryptoExtensionResult> {
      // ...
      let certInfoSetArray: Array<HuksCryptoExtensionCertInfo> = \[\]
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
        certs: certInfoSetArray
      };
    
      let res: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      }
      try {
        // 场景：导出所有证书成功
        let driver: YourUKeyDriver = YourDriverInstance;
        res = driver.YourDriver\_onEnumCertificates(...);
        result.resultCode = res.resultCode
        result.certs = res.certs
      } catch (error) {
        // 场景：导出所有证书失败
        result.resultCode = res.resultCode
        console.error(\`promise: onEnumCertificates failed\`);
      }
      return Promise.resolve(result);
    }
    
    （12）从API版本26.0.0开始，onGetResourceId用于获取密钥扩展能力的资源ID。params中需携带以下必选参数：[HUKS\_EXT\_CRYPTO\_TAG\_ABILITY\_NAME](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)表示Ability名称、[HUKS\_EXT\_CRYPTO\_TAG\_BUNDLE\_NAME](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)表示Bundle名称、[HUKS\_EXT\_CRYPTO\_TAG\_RESOURCE\_INFO](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huksexternalcrypto#huksexternalcryptotag)表示厂商自定义的资源信息。当调用成功时，返回值中的resultCode成员设置为0，resourceId成员非空。调用失败时，resultCode携带错误码信息。
    
    onGetResourceId(params: huksExternalCrypto.HuksExternalCryptoParam\[\]): Promise<HuksCryptoExtensionResult> {
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
    
      // 获取必选参数：资源信息
      let resourceInfo: Uint8Array | undefined = params.find((param =>
        param.tag === huksExternalCrypto.HuksExternalCryptoTag.HUKS\_EXT\_CRYPTO\_TAG\_RESOURCE\_INFO))?.value as Uint8Array;
      if (resourceInfo === undefined) {
        return Promise.resolve(result);
      }
       
      try {
        let driver: YourUKeyDriver = YourDriverInstance;
        let resourceId: string = driver.YourDriver\_onGetResourceId(abilityName, bundleName, resourceInfo);
        result.resultCode = 0;
        result.resourceId = resourceId;
      } catch (error) {
        result.resultCode = HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL;
        console.error('promise: onGetResourceId failed.');
      }
      return Promise.resolve(result);
    }
    
    （13）从API版本26.0.0开始，onImportCertificate用于导入证书到扩展设备。certInfo包含待导入的证书信息，包括证书用途、资源ID和证书数据。当调用成功时，返回值中的resultCode成员设置为0。调用失败时，resultCode携带错误码信息。
    
    onImportCertificate(handle: string, certInfo: HuksCryptoExtensionCertInfo, params?: huksExternalCrypto.HuksExternalCryptoParam\[\]): Promise<HuksCryptoExtensionResult> {
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
      
      try {
        let driver: YourUKeyDriver = YourDriverInstance;
        result = driver.YourDriver\_onImportCertificate(handle, certInfo, params);
        result.resultCode = 0;
      } catch (error) {
        result.resultCode = HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL;
        console.error('promise: onImportCertificate failed.');
      }
      return Promise.resolve(result);
    }
    
    （14）从API版本26.0.0开始，onGenerateKeyItem用于在扩展设备内生成密钥对。params中的参数为可选参数，由Extension厂商定义支持范围。如未传入相应参数，厂商需设置默认行为。当调用成功时，返回值中的resultCode成员设置为0；调用失败时，resultCode携带错误码信息。
    
    onGenerateKeyItem(handle: string, params: huks.HuksParam\[\]): Promise<HuksCryptoExtensionResult> {
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
    
      // 解析可选参数
      let algorithm: huks.HuksKeyAlg | undefined = params.find(
        param => param.tag === huks.HuksTag.HUKS\_TAG\_ALGORITHM)?.value as huks.HuksKeyAlg;
      let keySize: huks.HuksKeySize | undefined = params.find(
        param => param.tag === huks.HuksTag.HUKS\_TAG\_KEY\_SIZE)?.value as huks.HuksKeySize;
      let purpose: huks.HuksKeyPurpose | undefined = params.find(
        param => param.tag === huks.HuksTag.HUKS\_TAG\_PURPOSE)?.value as huks.HuksKeyPurpose;
    
      // 如未传入参数，设置默认值
      if (algorithm === undefined) {
        algorithm = huks.HuksKeyAlg.HUKS\_ALG\_RSA;
      }
      if (keySize === undefined) {
        keySize = huks.HuksKeySize.HUKS\_RSA\_KEY\_SIZE\_2048;
      }
      if (purpose === undefined) {
        purpose = huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_SIGN;
      }
        
      try {
        let driver: YourUKeyDriver = YourDriverInstance;
        result = driver.YourDriver\_onGenerateKeyItem(handle, algorithm, keySize, purpose);
        result.resultCode = 0;
      } catch (error) {
        result.resultCode = HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL;
        console.error('promise: onGenerateKeyItem failed.');
      }
      return Promise.resolve(result);
    }
    
    （15）从API版本26.0.0开始，onExportKeyItem用于导出指定密钥的公钥。params中的参数为可选参数，由Extension厂商定义支持范围。如未传入相应参数，厂商需设置默认行为。推荐传入密钥用途（HUKS\_TAG\_PURPOSE）参数，以便导出指定用途的公钥。当调用成功时，返回值中的resultCode成员设置为0，outData携带导出的公钥数据；调用失败时，resultCode携带错误码信息。
    
    onExportKeyItem(handle: string, params: huks.HuksParam\[\]): Promise<HuksCryptoExtensionResult> {
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
    
      // 解析可选参数，推荐传入密钥用途
      let purpose: huks.HuksKeyPurpose | undefined = params.find(
        param => param.tag === huks.HuksTag.HUKS\_TAG\_PURPOSE)?.value as huks.HuksKeyPurpose;
    
      // 如未传入用途参数，设置默认值（推荐默认签名用途）
      if (purpose === undefined) {
        purpose = huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_SIGN;
      }
       
      try {
        let driver: YourUKeyDriver = YourDriverInstance;
        let pubKey: Uint8Array = driver.YourDriver\_onExportKeyItem(handle, purpose);
        result.resultCode = 0;
        result.outData = pubKey;
      } catch (error) {
        result.resultCode = HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL;
        console.error('promise: onExportKeyItem failed.');
      }
      return Promise.resolve(result);
    }
    
    （16）从API版本26.0.0开始，onImportWrappedKeyItem用于导入加密封装的密钥对。params中的参数为可选参数，由Extension厂商定义支持范围。如未传入相应参数，厂商需设置默认行为。wrappedHandle用于指定解封密钥的密钥资源句柄，wrappedKey为封装密钥数据。当调用成功时，返回值中的resultCode成员设置为0；调用失败时，resultCode携带错误码信息。
    
    onImportWrappedKeyItem(handle: string, wrappedHandle: string, params: huks.HuksParam\[\], wrappedKey: Uint8Array): Promise<HuksCryptoExtensionResult> {
      let result: HuksCryptoExtensionResult = {
        resultCode: HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL,
      };
    
      // 解析可选参数
      let algorithm: huks.HuksKeyAlg | undefined = params.find(
        param => param.tag === huks.HuksTag.HUKS\_TAG\_ALGORITHM)?.value as huks.HuksKeyAlg;
      let keySize: huks.HuksKeySize | undefined = params.find(
        param => param.tag === huks.HuksTag.HUKS\_TAG\_KEY\_SIZE)?.value as huks.HuksKeySize;
      let purpose: huks.HuksKeyPurpose | undefined = params.find(
        param => param.tag === huks.HuksTag.HUKS\_TAG\_PURPOSE)?.value as huks.HuksKeyPurpose;
    
      // 如未传入参数，设置默认值
      if (algorithm === undefined) {
        algorithm = huks.HuksKeyAlg.HUKS\_ALG\_RSA;
      }
      if (keySize === undefined) {
        keySize = huks.HuksKeySize.HUKS\_RSA\_KEY\_SIZE\_2048;
      }
      if (purpose === undefined) {
        purpose = huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_ENCRYPT;
      }
       
      try {
        let driver: YourUKeyDriver = YourDriverInstance;
        result = driver.YourDriver\_onImportWrappedKeyItem(handle, wrappedHandle, algorithm, keySize, purpose, wrappedKey);
        result.resultCode = 0;
      } catch (error) {
        result.resultCode = HuksCryptoExtensionResultCode.HUKS\_CRYPTO\_EXTENSION\_ERR\_EXTENSION\_FAIL;
        console.error('promise: onImportWrappedKeyItem failed.');
      }
      return Promise.resolve(result);
    }
    

#### 驱动应用注册、解注册CryptoExtensionAbility适配

#### \[h2\]注册CryptoExtensionAbility

驱动HAP检测到Ukey存在时，向系统注册CryptoExtensionAbility。例如：Ukey插入等。

**示例：**

// ./ets/cryptoability/CryptoAbility.ts

import { huksExternalCrypto } from '@kit.UniversalKeystoreKit';

let ExtPropertiesTemp: Array<huksExternalCrypto.HuksExternalCryptoParam> = \[
  {
      tag: huksExternalCrypto.HuksExternalCryptoTag.HUKS\_EXT\_CRYPTO\_TAG\_ABILITY\_NAME,
      value: stringToUint8Array("YourCryptoExtensionName")
  }
\]

// provider名称，为保证全局唯一，建议包含厂商信息。
let provider = "testProvider"
huksExternalCrypto.registerProvider(provider, ExtPropertiesTemp);

#### \[h2\]解注册CryptoExtensionAbility

驱动HAP检测到Ukey不存在时，向系统解注册CryptoExtensionAbility。例如：Ukey拔出等。

**示例：**

huksExternalCrypto.unregisterProvider(provider, ExtPropertiesTemp);