离线匿名密钥证明(ArkTS)
===============

从API版本26.0.0开始，HUKS支持离线匿名密钥证明。该接口用于在无网络环境下证明密钥的合法性，与在线匿名密钥证明相比，在离线证书有效期内不需要网络连接，推荐优先使用离线匿名密钥证明。离线证书是在该流程中由三级CA颁发的证书，其有效期为1个月。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/78/v3/WbHoFCkpTQGN_K1t0cE0NA/caution_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132425Z&HW-CC-Expire=86400&HW-CC-Sign=54B3BA24DCF64FCE796203255DE6523E77933E1D7AE929DB0D39215FC220D245)

*   离线匿名密钥证明依赖网络，需要定期联网使用该接口以更新离线证书。
*   离线匿名密钥证明需保证本地时间是准确的，否则可能导致对端校验证书超期失败。

#### 开发步骤

1.  指定密钥别名，密钥别名命名规范参考[密钥生成介绍及算法规格](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-generation-overview)。
    
2.  初始化参数集。
    
    [HuksParam\[\]](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#huksparam)中的HuksParam字段参数必须包含[HUKS\_TAG\_ATTESTATION\_CHALLENGE](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#hukstag)属性，可选参数包含[HUKS\_TAG\_ATTESTATION\_ID\_VERSION\_INFO](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#hukstag)、[HUKS\_TAG\_ATTESTATION\_ID\_ALIAS](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#hukstag)属性。
    
3.  生成非对称密钥，具体请参考[密钥生成](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-generation-overview)。
    
4.  将密钥别名与参数集作为参数传入[anonAttestKeyItemOffline](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#huksanonattestkeyitemoffline)方法中，即可进行离线匿名密钥证明。
    

#### 开发案例

import { huks } from "@kit.UniversalKeystoreKit";
import { BusinessError } from "@kit.BasicServicesKit";

function StringToUint8Array(str: string) {
  let arr: number\[\] = new Array();
  for (let i = 0, j = str.length; i < j; ++i) {
    arr.push(str.charCodeAt(i));
  }
  return new Uint8Array(arr);
}

let g\_challenge: Uint8Array = StringToUint8Array("hi\_challenge\_data");
let g\_keyAlias: Uint8Array = StringToUint8Array("testKey");

let gCommonParam: Array<huks.HuksParam> = \[
  { tag: huks.HuksTag.HUKS\_TAG\_ATTESTATION\_CHALLENGE, value: g\_challenge },
  { tag: huks.HuksTag.HUKS\_TAG\_ATTESTATION\_ID\_ALIAS, value: g\_keyAlias },
\];

let gKeyParam: Array<huks.HuksParam> = \[
  {
    tag: huks.HuksTag.HUKS\_TAG\_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS\_ALG\_ECC
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_KEY\_SIZE,
    value: huks.HuksKeySize.HUKS\_ECC\_KEY\_SIZE\_256
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_SIGN | huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_VERIFY
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_PADDING,
    value: huks.HuksKeyPadding.HUKS\_PADDING\_NONE
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_DIGEST,
    value: huks.HuksKeyDigest.HUKS\_DIGEST\_SHA256
  }
\]

let gKeyOption: huks.HuksOptions = { properties: gKeyParam };

async function AnonAttestKeyOfflineTest() {
  let testKeyAlias: string = "testKey";
  await huks.generateKeyItem(testKeyAlias, gKeyOption);

  await huks.anonAttestKeyItemOffline(testKeyAlias, gCommonParam).then((data) => {
    console.info("anonAttestKeyItemOffline success")
  }).catch((error: BusinessError) =>
    console.error(\`anonAttestKeyItemOffline error ${JSON.stringify(error)}\`))
}