菜单
开源版

importKey

importKey() 从外部可移植格式导入密钥,并为您提供一个可用于 Web Crypto API 的 CryptoKey 对象。

用法

importKey(format, keyData, algorithm, extractable, keyUsages)

参数

名称类型描述
formatstring定义要导入密钥的数据格式。根据算法和密钥类型,数据格式可能不同。目前支持的格式有 rawjwkspkipkcs8
keyDataArrayBufferTypedArrayDataViewJsonWebKey导入密钥的数据。
algorithm一个 string 或包含单个 name string 属性的对象用于导入密钥的算法。
extractableboolean指示是否可以使用 exportKey 导出密钥。
keyUsagesArray<string>一个字符串数组,描述可使用该密钥执行的操作。目前支持的用法包括 encryptdecryptsignverify

支持的算法

AES-CBCAES-CTRAES-GCMAES-KWECDHECDSAHMACRSA-OAEPRSASSA-PKCS1-v1_5RSA-PSS
AesCbcParamsAesCtrParamsAesGcmParamsEcdhKeyDeriveParamsEcdsaParamsHmacKeyGenParamsRsaHashedImportParamsRsaHashedImportParamsRsaHashedImportParams

支持的格式

  • ECDHECDSA 算法支持 pkcs8spkirawjwk 格式。
  • RSA-OAEPRSASSA-PKCS1-v1_5RSA-PSS 算法支持 pkcs8spkijwk 格式。
  • AES-*HMAC 算法目前支持 rawjwk 格式。

返回值

一个 Promise,它解析为导入的密钥,作为 CryptoKey 对象。

抛出

类型描述
SyntaxErrorkeyUsages 参数为空但密钥类型为 secretprivate 时抛出。
TypeError尝试使用无效格式,或 keyData 不适合该格式时抛出。

示例

密钥导出/导入往返

JavaScript
export default async function () {
  /**
   * Generate a symmetric key using the AES-CBC algorithm.
   */
  const generatedKey = await crypto.subtle.generateKey(
    {
      name: 'AES-CBC',
      length: '256',
    },
    true,
    ['encrypt', 'decrypt']
  );

  /**
   * Export the key in raw format.
   */
  const exportedKey = await crypto.subtle.exportKey('raw', generatedKey);

  /**
   * Reimport the key in raw format to verify its integrity.
   */
  const importedKey = await crypto.subtle.importKey('raw', exportedKey, 'AES-CBC', true, [
    'encrypt',
    'decrypt',
  ]);

  console.log(JSON.stringify(importedKey));
}

导入静态 raw 密钥并解密传输的数据

本示例演示如何导入静态 raw 密钥并解密 base64 编码的传输数据。本例中的传输数据表示初始化向量和编码数据,在实际场景中,它可以是响应体或从请求接收的其他数据。

JavaScript
import { b64decode } from 'k6/encoding';

export default async function () {
  const transmittedData = base64Decode(
    'whzEN310mrlWIH/icf0dMquRZ2ENyfOzkvPuu92WR/9F8dbeFM8EGUVNIhaS'
  );

  // keyData is the key used to decrypt the data, which is usually stored in a secure location
  // for this example, we are using a static key
  const keyData = new Uint8Array([
    109, 151, 76, 33, 232, 253, 176, 90, 94, 40, 146, 227, 139, 208, 245, 139, 69, 215, 55, 197, 43,
    122, 160, 178, 228, 104, 4, 115, 138, 159, 119, 49,
  ]);

  try {
    const result = await decrypt(keyData, transmittedData);

    // should output decrypted message
    // INFO[0000] result: 'my secret message'  source=console
    console.log("result: '" + result + "'");
  } catch (e) {
    console.log('Error: ' + JSON.stringify(e));
  }
}

const decrypt = async (keyData, transmittedData) => {
  const initializeVectorLength = 12;

  // the first 12 bytes are the initialization vector
  const iv = new Uint8Array(transmittedData.subarray(0, initializeVectorLength));

  // the rest of the transmitted data is the encrypted data
  const encryptedData = new Uint8Array(transmittedData.subarray(initializeVectorLength));

  const importedKey = await crypto.subtle.importKey(
    'raw',
    keyData,
    { name: 'AES-GCM', length: '256' },
    true,
    ['decrypt']
  );

  const plain = await crypto.subtle.decrypt(
    { name: 'AES-GCM', iv: iv },
    importedKey,
    encryptedData
  );

  return arrayBufferToString(plain);
};

const arrayBufferToString = (buffer) => {
  return String.fromCharCode.apply(null, new Uint8Array(buffer));
};

const base64Decode = (base64String) => {
  return new Uint8Array(b64decode(base64String));
};

导入静态 JWK 密钥并解密传输的数据

本示例与上一个类似。它演示如何导入静态 jwk 密钥并解密 base64 编码的传输数据(包含初始化向量和编码数据)。

JavaScript
import { b64decode } from 'k6/encoding';

export default async function () {
  // transmitted data is the base64 of the initialization vector + encrypted data
  // that unusually transmitted over the network
  const transmittedData = base64Decode(
    'drCfxl4O+5FcrHe8Bs0CvKlw3gZpv+S5if3zn7c4BJzHJ35QDFV4sJB0pbDT'
  );

  // keyData is the key used to decrypt the data, which is usually stored in a secure location
  // for this example, we are using a static key
  const jwkKeyData = {
    kty: 'oct',
    ext: true,
    key_ops: ['decrypt', 'encrypt'],
    alg: 'A256GCM',
    k: '9Id_8iG6FkGOWmc1S203vGVnTExtpDGxdQN7v7OV9Uc',
  };

  try {
    const result = await decrypt(jwkKeyData, transmittedData);

    // should output decrypted message
    // INFO[0000] result: 'my secret message'  source=console
    console.log("result: '" + result + "'");
  } catch (e) {
    console.log('Error: ' + JSON.stringify(e));
  }
}

const decrypt = async (keyData, transmittedData) => {
  const initializeVectorLength = 12;

  // the first 12 bytes are the initialization vector
  const iv = new Uint8Array(transmittedData.subarray(0, initializeVectorLength));

  // the rest of the transmitted data is the encrypted data
  const encryptedData = new Uint8Array(transmittedData.subarray(initializeVectorLength));

  const importedKey = await crypto.subtle.importKey(
    'jwk',
    keyData,
    { name: 'AES-GCM', length: 256 },
    true,
    ['encrypt', 'decrypt']
  );

  const plain = await crypto.subtle.decrypt(
    { name: 'AES-GCM', iv: iv },
    importedKey,
    encryptedData
  );

  return arrayBufferToString(plain);
};

const arrayBufferToString = (buffer) => {
  return String.fromCharCode.apply(null, new Uint8Array(buffer));
};

const base64Decode = (base64String) => {
  return new Uint8Array(b64decode(base64String));
};