加密导出导入密钥(ArkTS)
===============

从API 20开始，支持加密导出导入密钥。

当前指导提供以下加密导出导入密钥示例：

*   [加密导出导入普通密钥](#加密导出导入普通密钥)
*   [普通密钥导入为群组密钥](#普通密钥导入为群组密钥)

#### 开发步骤

1.  初始化生成密钥属性集，需要设置[HUKS\_TAG\_IS\_ALLOWED\_WRAP](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#hukstag)，指定密钥允许导出。
    
2.  调用[generateKeyItem](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#huksgeneratekeyitem9)生成密钥，具体请参考[密钥生成](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-key-generation-overview)。
    
3.  调用[wrapKeyItem](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#hukswrapkeyitem20)加密导出密钥。
    
4.  调用[unwrapKeyItem](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-huks#huksunwrapkeyitem20)加密导入密钥。如果是从普通密钥导入为群组密钥，需要传入TUI PIN类型的AuthToken，认证TUI PIN并获取AuthToken请参考[数字盾服务](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/devicesecurity-trustedauth-verifybypwd#开发步骤)。
    

#### 开发案例

#### \[h2\]加密导出导入普通密钥

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

let keyAlias = "testWrapKey";
let properties: Array<huks.HuksParam> = \[
  {
    tag: huks.HuksTag.HUKS\_TAG\_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS\_ALG\_AES
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_KEY\_SIZE,
    value: huks.HuksKeySize.HUKS\_AES\_KEY\_SIZE\_256
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_ENCRYPT | huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_DECRYPT
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_PADDING,
    value: huks.HuksKeyPadding.HUKS\_PADDING\_NONE
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_BLOCK\_MODE,
    value: huks.HuksCipherMode.HUKS\_MODE\_GCM
  },
  /\* 生成密钥时指定允许加密导出 \*/
  {
    tag: huks.HuksTag.HUKS\_TAG\_IS\_ALLOWED\_WRAP,
    value: true
  }
\];

let options: huks.HuksOptions = {
  properties: properties,
};

let wrapKeyProperties: Array<huks.HuksParam> = \[
  {
    tag: huks.HuksTag.HUKS\_TAG\_KEY\_WRAP\_TYPE,
    value: huks.HuksKeyWrapType.HUKS\_KEY\_WRAP\_TYPE\_HUK\_BASED
  }
\];

let wrapKeyOptions: huks.HuksOptions = {
  properties: wrapKeyProperties,
};

let wrappedKey: Uint8Array;

async function testGenerateKey() {
  await huks.generateKeyItem(keyAlias, options)
    .then((data) => {
      console.info(\`promise: generateKeyItem success\`);
    })
    .catch((error: Error) => {
      console.error(\`promise: generateKeyItem failed\`);
    });
}

async function testWrapKey(){
  await testGenerateKey();

  await huks.wrapKeyItem(keyAlias, wrapKeyOptions)
    .then((data) => {
      wrappedKey = data.outData as Uint8Array;
      console.info(\`promise: wrapKeyItem success, data = ${JSON.stringify(data)}\`);
    })
    .catch((error: Error) => {
      console.error(\`promise: wrapKeyItem failed\`);
    });

  await huks.unwrapKeyItem(keyAlias, wrapKeyOptions, wrappedKey)
    .then((data) => {
      console.info(\`promise: unwrapKeyItem success\`);
    })
    .catch((error: Error) => {
      console.error(\`promise: unwrapKeyItem failed\`);
    });
}

#### \[h2\]普通密钥导入为群组密钥

从API 23开始，支持从普通密钥导入为群组密钥。

import { huks } from '@kit.UniversalKeystoreKit';
import { trustedAuthentication } from '@kit.DeviceSecurityKit';

let keyAlias = "testWrapKey";
let properties: Array<huks.HuksParam> = \[
  {
    tag: huks.HuksTag.HUKS\_TAG\_ALGORITHM,
    value: huks.HuksKeyAlg.HUKS\_ALG\_AES
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_KEY\_SIZE,
    value: huks.HuksKeySize.HUKS\_AES\_KEY\_SIZE\_256
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_PURPOSE,
    value: huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_ENCRYPT | huks.HuksKeyPurpose.HUKS\_KEY\_PURPOSE\_DECRYPT
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_PADDING,
    value: huks.HuksKeyPadding.HUKS\_PADDING\_NONE
  },
  {
    tag: huks.HuksTag.HUKS\_TAG\_BLOCK\_MODE,
    value: huks.HuksCipherMode.HUKS\_MODE\_GCM
  },
  /\* 生成密钥时指定允许加密导出 \*/
  {
    tag: huks.HuksTag.HUKS\_TAG\_IS\_ALLOWED\_WRAP,
    value: true
  }
\];

let options: huks.HuksOptions = {
  properties: properties,
};

let wrapKeyProperties: Array<huks.HuksParam> = \[
  {
    tag: huks.HuksTag.HUKS\_TAG\_KEY\_WRAP\_TYPE,
    value: huks.HuksKeyWrapType.HUKS\_KEY\_WRAP\_TYPE\_HUK\_BASED
  }
\];

let wrapKeyOptions: huks.HuksOptions = {
  properties: wrapKeyProperties,
};

let wrappedKey: Uint8Array;

async function testGenerateKey() {
  await huks.generateKeyItem(keyAlias, options)
    .then((data) => {
      console.info(\`promise: generateKeyItem success\`);
    })
    .catch((error: Error) => {
      console.error(\`promise: generateKeyItem failed\`);
    });
}

async function testWrapKey(){
  await testGenerateKey();

  await huks.wrapKeyItem(keyAlias, wrapKeyOptions)
    .then((data) => {
      wrappedKey = data.outData as Uint8Array;
      console.info(\`promise: wrapKeyItem success, data = ${JSON.stringify(data)}\`);
    })
    .catch((error: Error) => {
      console.error(\`promise: wrapKeyItem failed\`);
    });

  challenge = new Uint8Array(32);
  let label: trustedAuthentication.TUILable;
  let authID: bigint;
  /\* 认证TUI PIN之前需要先创建数字盾，请参考数字盾服务，authID和label仅做示例 \*/
  let authToken = await trustedAuthentication.trustedAuthentication(challenge, authID, label);
  wrapKeyOptions.wrapKeyProperties.push({
    tag: huks.HuksTag.HUKS\_TAG\_AUTH\_TOKEN,
    value: authToken.authToken
  })

  await huks.unwrapKeyItem(keyAlias, wrapKeyOptions, wrappedKey)
    .then((data) => {
      console.info(\`promise: unwrapKeyItem success\`);
    })
    .catch((error: Error) => {
      console.error(\`promise: unwrapKeyItem failed\`);
    });
}