# 签名/验签(ArkTS)

当前指导提供以下示例，供开发者参考完成签名、验签开发：

*   密钥算法为RSA、摘要算法为SHA256、填充模式为PSS

具体的场景介绍及支持的算法规格，请参考签名/验签介绍及算法规格。

#### 开发步骤

**签名**

1.  通过证书管理系统能力提供的证书选择接口获取keyUri作为resourceId，并作为密钥别名，打开资源后完成PIN码认证。
    
2.  指定待签名的明文数据。
    
3.  获取属性参数HuksOptions，包括两个字段properties和inData。inData传入明文数据，properties传入算法参数配置。
    
4.  调用initSession初始化密钥会话，并获取会话的句柄handle。
    
5.  调用finishSession结束密钥会话，获取签名signature。
    

**验签**

1.  通过证书管理系统能力提供的证书选择接口获取keyUri作为resourceId，并作为密钥别名，然后打开资源。
    
2.  获取待验证的签名。
    
3.  获取属性参数HuksOptions，包括两个字段properties和inData。inData传入签名signature，properties传入算法参数配置。
    
4.  调用initSession初始化密钥会话，并获取会话的句柄handle。
    
5.  调用updateSession更新密钥会话。
    
6.  调用finishSession结束密钥会话，验证签名。
    

#### 开发案例

#### RSA/SHA256/PSS

```
/*
 * 密钥算法为RSA，摘要算法为SHA256，填充模式为PSS
 */
import { huks } from '@kit.UniversalKeystoreKit';
import { BusinessError } from '@kit.BasicServicesKit';

let handle: number;
let plaintext = '123456';
let signature: Uint8Array;

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

function Uint8ArrayToString(fileData: Uint8Array) {
  let dataString = '';
  for (let i = 0; i < fileData.length; i++) {
    dataString += String.fromCharCode(fileData[i]);
  }
  return dataString;
}

function GetRsaSignProperties() {
  let properties: Array<huks.HuksParam> = [{
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_RSA
  }, {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048
  }, {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_PSS
  }, {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
  }, {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN
  }, {
    tag: huks.HuksTag.HUKS_TAG_KEY_CLASS,
    value: huks.HuksKeyClassType.HUKS_KEY_CLASS_EXTENSION
  }];
  return properties;
}

function GetRsaVerifyProperties() {
  let properties: Array<huks.HuksParam> = [{
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS_ALG_RSA
  }, {
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE,
    value: huks.HuksKeySize.HUKS_RSA_KEY_SIZE_2048
  }, {
    tag: huks.HuksTag.HUKS_TAG_PADDING,
    value: huks.HuksKeyPadding.HUKS_PADDING_PSS
  }, {
    tag: huks.HuksTag.HUKS_TAG_DIGEST,
    value: huks.HuksKeyDigest.HUKS_DIGEST_SHA256
  }, {
    tag: huks.HuksTag.HUKS_TAG_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY
  }, {
    tag: huks.HuksTag.HUKS_TAG_KEY_CLASS,
    value: huks.HuksKeyClassType.HUKS_KEY_CLASS_EXTENSION
  }];
  return properties;
}

async function initSession(keyAlias: string, huksOptions: huks.HuksOptions) {
  console.info(`promise: enter initSession`);
  try {
    await huks.initSession(keyAlias, huksOptions)
      .then((data) => {
        handle = data.handle;
        console.info(`promise: initSession success`);
      }).catch((error: BusinessError) => {
        console.error(`promise: initSession failed, errCode : ${error.code}, errMsg : ${error.message}`);
      })
  } catch (error) {
    console.error(`promise: initSession input arg invalid`);
  }
}

async function updateSession(handle: number, huksOptions: huks.HuksOptions) {
  console.info(`promise: enter updateSession`);
  try {
    await huks.updateSession(handle, huksOptions)
      .then((data) => {
        let outData = data.outData as Uint8Array;
        console.info(`promise: updateSession success, data = ${Uint8ArrayToString(outData)}`);
      }).catch((error: BusinessError) => {
        console.error(`promise: updateSession failed, errCode : ${error.code}, errMsg : ${error.message}`);
      })
  } catch (error) {
    console.error(`promise: updateSession input arg invalid`);
  }
}

async function finishSession(handle: number, huksOptions: huks.HuksOptions) {
  console.info(`promise: enter finishSession`);
  try {
    await huks.finishSession(handle, huksOptions)
      .then((data) => {
        signature = data.outData as Uint8Array;
        console.info(`promise: finishSession success, data = ${Uint8ArrayToString(signature)}`);
      }).catch((error: BusinessError) => {
        console.error(`promise: finishSession failed, errCode : ${error.code}, errMsg : ${error.message}`);
      })
  } catch (error) {
    console.error(`promise: finishSession input arg invalid`);
  }
}

async function Sign(keyAlias: string, plaintext: string) {
  console.info(`enter Sign`);
  let signProperties = GetRsaSignProperties();
  let options: huks.HuksOptions = {
    properties: signProperties,
  }
  await initSession(keyAlias, options);

  if (handle !== undefined) {
    options.inData = StringToUint8Array(plaintext);
    await finishSession(handle, options);
  }
}

async function Verify(keyAlias: string, plaintext: string, signature: Uint8Array) {
  console.info(`enter Verify`);
  let verifyProperties = GetRsaVerifyProperties();
  let options: huks.HuksOptions = {
    properties: verifyProperties,
  }

  await initSession(keyAlias, options);

  if (handle !== undefined) {
    options.inData = StringToUint8Array(plaintext);
    await updateSession(handle, options);
    options.inData = signature;
    await finishSession(handle, options);
  }
}

async function testSignVerify() {
  // 假设keyAlias是已获取的resourceId
  let keyAlias = JSON.stringify({
    providerName: "testProviderName",
    bundleName: "com.example.cryptoapplication",
    abilityName: "CryptoExtension",
    index: {
      key: "testKey"
    } as ESObject
  });
  await Sign(keyAlias, plaintext);
  await Verify(keyAlias, plaintext, signature);
}
```