应用端开发
=====

#### 接口说明

接口能力由[Universal Keystore Kit](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-overview)提供，涉及的功能指导请参考：

*   [Universal Keystore Kit简介](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-overview)
    
*   [查询密钥是否存在(ArkTS)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-check-key-arkts)
    
*   [查询密钥是否存在(C/C++)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-check-key-ndk)
    
*   [生成密钥(ArkTS)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-generation-arkts)
    
*   [生成密钥(C/C++)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-generation-ndk)
    
*   [在线匿名密钥证明(ArkTS)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-anon-attestation-arkts)
    
*   [在线匿名密钥证明(C/C++)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-anon-attestation-ndk)
    
*   [离线匿名密钥证明(ArkTS)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-offline-anon-attestation-arkts)
    
*   [签名/验签(ArkTS)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-signing-signature-verification-arkts)
    
*   [签名/验签(C/C++)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-signing-signature-verification-ndk)
    

#### 使用前提

使用应用的私钥对业务请求进行签名的前提是已经创建应用公私钥和在服务器保存了应用公钥，相关开发指南请参考：

*   [查询应用公私钥对是否存在](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/device-attestation-apps#查询应用公私钥对是否存在)
    
*   [创建应用公私钥对](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/device-attestation-apps#创建应用公私钥对)
    
*   [对应用公钥和应用ID进行证明](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/device-attestation-apps#对应用公钥和应用id进行证明)
    

#### 使用应用私钥对业务请求进行签名

在密钥证明流程处理成功后，您的应用在进行一些安全敏感的端云业务时，可以使用已验证的密钥对业务请求进行安全保护。

应用可以调用Universal Keystore Kit的签名接口，使用应用私钥对业务请求数据（如HTTP请求的Body）进行签名，然后把签名结果数据添加到请求消息中（如HTTP的Header字段）。为了方便应用服务器查找应用公钥用于验签，应用应该在业务请求中携带应用公钥ID。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/4d/v3/0PY3nlAQQJ2kFtRXwyPXbw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T132426Z&HW-CC-Expire=86400&HW-CC-Sign=F6E3B6FB9E99EB94036C8E693DFD74A7A615897E2453DCDB16A92D385406081A)

安全建议：为了在发送业务请求时能够防重放攻击，建议应用先从应用服务器获取一次性的挑战值Challenge。应用服务器采用安全随机数生成挑战值Challenge，并缓存到服务器中。

**示例：**

import { huks } from '@kit.UniversalKeystoreKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';

let keyAlias = 'serviceKey\_user01'; // 业务密钥别名
let handle: number;
let plaintext = '123456'; // 待签名的明文数据，建议包含服务器端返回的Challenge。
let signature: Uint8Array; // 存储签名结果数据的变量

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);
}

function GetSignProperties() {
  let properties: Array<huks.HuksParam> = new Array();
  let index = 0;
  properties\[index++\] = {
    tag: huks.HuksTag.HUKS\_TAG\_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS\_ALG\_ECC
  };
  properties\[index++\] = {
    tag: huks.HuksTag.HUKS\_TAG\_KEY\_SIZE,
    value: huks.HuksKeySize.HUKS\_AES\_KEY\_SIZE\_256
  };
  properties\[index++\] = {
    tag: huks.HuksTag.HUKS\_TAG\_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_SIGN
  };
  properties\[index++\] = {
    tag: huks.HuksTag.HUKS\_TAG\_DIGEST,
    value: huks.HuksKeyDigest.HUKS\_DIGEST\_SHA256
  }
  return properties;
}

async function Sign(keyAlias: string, plaintext: string) {
  let signProperties = GetSignProperties();
  let options: huks.HuksOptions = {
    properties: signProperties,
    inData: StringToUint8Array(plaintext)
  }
  await huks.initSession(keyAlias, options)
    .then((data) => {
      handle = data.handle;
    }).catch((err: BusinessError) => {
      console.error(\`promise: init sign failed, error: \` + err.message);
    })
  await huks.finishSession(handle, options)
    .then((data) => {
      signature = data.outData as Uint8Array;
  
      let base64 = new util.Base64Helper();
      let signatureBase64 = base64.encodeToStringSync(signature);
      // todo：把签名结果的Base64编码（signatureBase64变量）发送到云侧的服务器。如下示例代码把签名结果打印到日志中，供调测使用，商用代码不需要打印。
      console.info(\`sign success, result:\` + signatureBase64);
  
    }).catch((err: BusinessError) => {
      console.error(\`promise: sign failed, error: \` + err.message);
    })
}