SubtleCrypto: exportKey() 方法

Baseline 廣泛可用 *

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流瀏覽器均已支援。

* 此特性的某些部分可能存在不同級別的支援。

安全上下文: 此功能僅在安全上下文(HTTPS)中可用,且支援此功能的瀏覽器數量有限。

注意:此功能在 Web Workers 中可用。

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 上嘗試工作示例

原始匯出

此示例將 AES 金鑰匯出為包含金鑰位元組的 ArrayBuffer在 GitHub 上檢視完整程式碼

js
/*
Export the given key and write it into the "exported-key" space.
*/
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}]`;
}

/*
Generate an encrypt/decrypt secret key,
then set up an event listener on the "Export" button.
*/
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
/*
Convert an ArrayBuffer into a string
from https://developer.chrome.com/blog/how-to-convert-arraybuffer-to-and-from-string/
*/
function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}

/*
Export the given key and write it into the "exported-key" space.
*/
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;
}

/*
Generate a sign/verify key pair,
then set up an event listener on the "Export" button.
*/
window.crypto.subtle
  .generateKey(
    {
      name: "RSA-PSS",
      // Consider using a 4096-bit key for systems that require long-term security
      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
/*
Convert an ArrayBuffer into a string
from https://developer.chrome.com/blog/how-to-convert-arraybuffer-to-and-from-string/
*/
function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint8Array(buf));
}

/*
Export the given key and write it into the "exported-key" space.
*/
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;
}

/*
Generate an encrypt/decrypt key pair,
then set up an event listener on the "Export" button.
*/
window.crypto.subtle
  .generateKey(
    {
      name: "RSA-OAEP",
      // Consider using a 4096-bit key for systems that require long-term security
      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
/*
Export the given key and write it into the "exported-key" space.
*/
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, " ");
}

/*
Generate a sign/verify key pair,
then set up an event listener on the "Export" button.
*/
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);
    });
  });

規範

規範
Web 加密級別 2
# SubtleCrypto-method-exportKey

瀏覽器相容性

另見