SubtleCrypto.exportKey()

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

* Some parts of this feature may have varying levels of support.

安全上下文: 此项功能仅在一些支持的浏览器安全上下文(HTTPS)中可用。

SubtleCrypto 接口的 exportKey() 方法用于导出密钥。也就是说,它将一个 CryptoKey 对象作为输入,并给出对应的外部可移植格式的密钥。

若要导出密钥,密钥的 CryptoKey.extractable 必须设置为 true

密钥可导出为多种格式:请参阅 SubtleCrypto.importKey() 页面支持的格式以获取详细信息。

密钥不会以加密的格式导出:要在导出密钥时对密钥进行加密,请使用 SubtleCrypto.wrapKey() API 代替。

语法

js
exportKey(format, key)

参数

format

一个描述要导出的密钥格式的字符串。可为以下值之一:

key

要导出的 CryptoKey

返回值

一个 Promise

  • 如果 formatjwk,则 promise 会兑现一个包含密钥的 JSON 对象。
  • 否则,promise 将会兑现一个包含密钥的 ArrayBuffer

异常

当发生以下几种异常时,promise 会被拒绝:

InvalidAccessError DOMException

若尝试导出不可导出的密钥,则会抛出此异常。

NotSupported DOMException

若尝试导出为未知的格式,则会抛出此异常。

TypeError

若尝试使用无效的格式,则会抛出此异常。

示例

备注: 你可以在 GitHub 上尝试可用的示例

导出为 Raw 格式

该示例将 AES 密钥导出为包含二进制密钥的 ArrayBuffer在 GitHub 上查看完整代码

js
/*
导出给定密钥,并将其写入“exported-key”的区域。
*/
async function exportCryptoKey(key) {
  const exported = await window.crypto.subtle.exportKey("raw", key);
  const exportedKeyBuffer = new Uint8Array(exported);

  const exportKeyOutput = document.querySelector(".exported-key");
  exportKeyOutput.textContent = `[${exportedKeyBuffer}]`;
}

/*
生成加密/解密密钥,
然后在“导出”按钮上设置事件监听器。
*/
window.crypto.subtle
  .generateKey(
    {
      name: "AES-GCM",
      length: 256,
    },
    true,
    ["encrypt", "decrypt"],
  )
  .then((key) => {
    const exportButton = document.querySelector(".raw");
    exportButton.addEventListener("click", () => {
      exportCryptoKey(key);
    });
  });

导出为 PKCS #8 格式

该示例将 RSA 私有签名密钥导出为 PKCS #8 对象。然后将导出的密钥编码为 PEM 格式。在 GitHub 上查看完整代码

js
/*
将 ArrayBuffer 转换为字符串
代码来自 https://developer.chrome.google.cn/blog/how-to-convert-arraybuffer-to-and-from-string
*/
function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}

/*
导出给定密钥,并将其写入“exported-key”的区域。
*/
async function exportCryptoKey(key) {
  const exported = await window.crypto.subtle.exportKey("pkcs8", key);
  const exportedAsString = ab2str(exported);
  const exportedAsBase64 = window.btoa(exportedAsString);
  const pemExported = `-----BEGIN PRIVATE KEY-----\n${exportedAsBase64}\n-----END PRIVATE KEY-----`;

  const exportKeyOutput = document.querySelector(".exported-key");
  exportKeyOutput.textContent = pemExported;
}

/*
生成签名/验证密钥对,
然后在“导出”按钮上设置事件监听器。
*/
window.crypto.subtle
  .generateKey(
    {
      name: "RSA-PSS",
      // 考虑为要求保证长期安全性的系统使用 4096 位的密钥
      modulusLength: 2048,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: "SHA-256",
    },
    true,
    ["sign", "verify"],
  )
  .then((keyPair) => {
    const exportButton = document.querySelector(".pkcs8");
    exportButton.addEventListener("click", () => {
      exportCryptoKey(keyPair.privateKey);
    });
  });

导出为 SubjectPublicKeyInfo 格式

该示例将 RSA 公开加密密钥导出为 PEM 编码的 SubjectPublicKeyInfo 对象。在 GitHub 上查看完整代码

js
/*
将 ArrayBuffer 转换为字符串
代码来自 https://developer.chrome.google.cn/blog/how-to-convert-arraybuffer-to-and-from-string
*/
function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}

/*
导出给定密钥,并将其写入“exported-key”的区域。
*/
async function exportCryptoKey(key) {
  const exported = await window.crypto.subtle.exportKey("spki", key);
  const exportedAsString = ab2str(exported);
  const exportedAsBase64 = window.btoa(exportedAsString);
  const pemExported = `-----BEGIN PUBLIC KEY-----\n${exportedAsBase64}\n-----END PUBLIC KEY-----`;

  const exportKeyOutput = document.querySelector(".exported-key");
  exportKeyOutput.textContent = pemExported;
}

/*
生成加密/解密密钥对,
然后在“导出”按钮上设置事件监听器。
*/
window.crypto.subtle
  .generateKey(
    {
      name: "RSA-OAEP",
      // 考虑为要求保证长期安全性的系统使用 4096 位的密钥
      modulusLength: 2048,
      publicExponent: new Uint8Array([1, 0, 1]),
      hash: "SHA-256",
    },
    true,
    ["encrypt", "decrypt"],
  )
  .then((keyPair) => {
    const exportButton = document.querySelector(".spki");
    exportButton.addEventListener("click", () => {
      exportCryptoKey(keyPair.publicKey);
    });
  });

导出为 JSON Web Key 格式

该示例将 ECDSA 私有签名密钥导出为 JSON Web Key 对象。在 GitHub 上查看完整代码

js
/*
导出给定密钥,并将其写入“exported-key”的区域。
*/
async function exportCryptoKey(key) {
  const exported = await window.crypto.subtle.exportKey("jwk", key);
  const exportKeyOutput = document.querySelector(".exported-key");
  exportKeyOutput.textContent = JSON.stringify(exported, null, " ");
}

/*
生成签名/验证密钥对,
然后在“导出”按钮上设置事件监听器。
*/
window.crypto.subtle
  .generateKey(
    {
      name: "ECDSA",
      namedCurve: "P-384",
    },
    true,
    ["sign", "verify"],
  )
  .then((keyPair) => {
    const exportButton = document.querySelector(".jwk");
    exportButton.addEventListener("click", () => {
      exportCryptoKey(keyPair.privateKey);
    });
  });

规范

Specification
Web Cryptography API
# SubtleCrypto-method-exportKey

浏览器兼容性

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
exportKey
Ed25519 algorithm
X25519 algorithm

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Partial support
Partial support
In development. Supported in a pre-release version.
In development. Supported in a pre-release version.
No support
No support
See implementation notes.
User must explicitly enable this feature.
Has more compatibility info.

参见