共用方式為


適用於 JavaScript 的 Azure Key Vault 金鑰用戶端庫 - 版本 4.10.0

Azure Key Vault 是一項服務,可讓您使用安全密鑰來加密驗證金鑰、記憶體帳戶密鑰、數據加密密鑰、.pfx 檔案和密碼。 如果您想要深入瞭解 Azure Key Vault,建議您檢閱:什麼是 Azure Key Vault?

Azure Key Vault 受控 HSM 是完全受控、高可用性、符合標準標準的雲端服務,可讓您使用 FIPS 140-2 層級 3 驗證的 HSM 來保護雲端應用程式的密碼編譯密鑰。 如果您想要深入瞭解 Azure Key Vault 受控 HSM,您可以檢閱:什麼是 Azure Key Vault 受控 HSM?

Azure Key Vault 金鑰連結庫用戶端在針對受控 HSM 執行時,支援 RSA 金鑰、橢圓曲線 (EC) 金鑰,以及對稱式 (oct) 金鑰,每個金鑰都支援硬體安全性模組 (HSM) 中的對應支援。 它提供建立、擷取、更新、刪除、清除、備份、還原,以及列出密鑰及其版本的作業。

在 Node.js 應用程式中,使用 Azure Key Vault 金鑰的用戶端連結庫來:

  • 使用省略號曲線或 RSA 加密建立金鑰,選擇性地由硬體安全性模組 (HSM) 支援。
  • 匯入、刪除和更新金鑰。
  • 使用其屬性取得一或多個金鑰和已刪除的索引鍵。
  • 復原已刪除的金鑰並還原備份的金鑰。
  • 取得金鑰的版本。

使用此連結庫中可用的密碼編譯用戶端,您也可以存取:

  • 加密
  • 解密
  • 簽署
  • 驗證
  • 包裝索引鍵
  • 解除包裝金鑰

注意:由於 Azure Key Vault 服務限制,無法在瀏覽器中使用此套件,請參閱本檔 以取得指引。

主要連結:

入門指南

目前支援的環境

先決條件

安裝套件

使用 npm 安裝 Azure Key Vault 金鑰客戶端連結庫

npm install @azure/keyvault-keys

安裝身分識別連結庫

Azure Key Vault 用戶端會使用 Azure 身分識別連結庫進行驗證。 使用 npm 安裝

npm install @azure/identity

設定 TypeScript

TypeScript 用戶必須安裝 Node 類型定義:

npm install @types/node

您也需要在 tsconfig.json中啟用 compilerOptions.allowSyntheticDefaultImports。 請注意,如果您已啟用 compilerOptions.esModuleInterop,預設會啟用 allowSyntheticDefaultImports。 如需詳細資訊,請參閱 TypeScript 的編譯程式選項手冊

重要概念

  • 金鑰用戶端 是主要介面,可從 JavaScript 應用程式與 Azure Key Vault API 中密鑰相關的 API 方法互動。 初始化之後,它會提供一組基本方法,可用來建立、讀取、更新和刪除密鑰。
  • 金鑰版本 是 Key Vault 中的金鑰版本。 每次使用者將值指派給唯一索引鍵名稱時,就會建立該密鑰的新 版本。 除非提供特定版本給查詢,否則依名稱擷取索引鍵一律會傳回指派的最新值。
  • 虛刪除 可讓Key Vault支援刪除和清除兩個不同的步驟,因此不會立即遺失已刪除的密鑰。 只有當 Key Vault 已啟用虛刪除 時,才會發生這種情況。
  • 您可以從任何建立的金鑰產生 金鑰備份。 這些備份是二進位數據,而且只能用來重新產生先前刪除的密鑰。
  • 密碼編譯用戶端 是與 Key Vault API 中密鑰 API 方法互動的個別介面。 此用戶端僅著重於可以使用已在 Key Vault 中建立的密鑰來執行的密碼編譯作業。 如需此用戶端的詳細資訊,請參閱 密碼編譯 一節。

使用 Azure Active Directory 進行驗證

Key Vault 服務依賴 Azure Active Directory 來驗證其 API 的要求。 @azure/identity 套件提供應用程式可用來執行這項作業的各種認證類型。 自述檔提供更多詳細數據和範例,讓您開始使用。

若要與 Azure Key Vault 服務互動,您必須建立 KeyClient 類別的實例、保存庫 url 和認證物件。 本檔中所示的範例會使用名為 DefaultAzureCredential的認證物件,適用於大部分案例,包括本機開發和生產環境。 此外,建議您在生產環境中使用 受控識別 進行驗證。

您可以在 Azure 身分識別檔中找到驗證方式及其對應認證類型的詳細資訊。

以下是快速範例。 首先,匯入 DefaultAzureCredentialKeyClient。 匯入這些項目之後,我們可以接著連線到 Key Vault 服務:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

// Build the URL to reach your key vault
const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`; // or `https://${vaultName}.managedhsm.azure.net` for managed HSM.

// Lastly, create our keys client and connect to the service
const client = new KeyClient(url, credential);

指定 Azure Key Vault 服務 API 版本

根據預設,此套件會使用最新的 Azure Key Vault 服務版本,7.2。 您可以藉由在用戶端建構函式中設定選項 serviceVersion 來變更所使用的服務版本,如下所示:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

// Build the URL to reach your key vault
const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`; // or `https://${vaultName}.managedhsm.azure.net` for managed HSM.

// Change the Azure Key Vault service API version being used via the `serviceVersion` option
const client = new KeyClient(url, credential, {
  serviceVersion: "7.0", // Or 7.1
});

範例

下列各節提供代碼段,這些代碼段涵蓋使用 Azure Key Vault 金鑰的一些常見工作。 這裡涵蓋的案例包括:

建立金鑰

createKey 會建立要儲存在 Azure Key Vault 中的密鑰。 如果已有相同名稱的金鑰存在,則會建立新版本的金鑰。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";
const result = await client.createKey(keyName, "RSA");
console.log("result: ", result);

傳送至 createKey 的第二個參數是索引鍵的類型。 支援的密鑰類型取決於 SKU,以及您使用的是 Azure Key Vault 或 Azure 受控 HSM。 如需支援的金鑰類型的 up-to日期清單,請參閱關於密鑰

取得金鑰

從保存庫讀取金鑰的最簡單方式是依名稱取得金鑰。 這會擷取最新版的金鑰。 如果您將其指定為選擇性參數的一部分,可以選擇性地取得不同的密鑰版本。

getKey 擷取 Key Vault 中先前儲存的金鑰。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

const latestKey = await client.getKey(keyName);
console.log(`Latest version of the key ${keyName}: `, latestKey);

const specificKey = await client.getKey(keyName, { version: latestKey.properties.version! });
console.log(`The key ${keyName} at the version ${latestKey.properties.version!}: `, specificKey);

使用屬性建立和更新金鑰

下列屬性也可以指派給 Key Vault 中的任何金鑰:

  • tags:可用於搜尋和篩選索引鍵的任何索引鍵/值集。
  • keyOps:此索引鍵可執行的作業陣列(encryptdecryptsignverifywrapKeyunwrapKey)。
  • enabled:布爾值,決定是否可以讀取索引鍵值。
  • notBefore:指定日期,之後可以擷取索引鍵值。
  • expires:指定日期之後無法擷取索引鍵值。

具有這些屬性的物件可以傳送為 createKey的第三個參數,緊接在索引鍵的名稱和值後面,如下所示:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

const result = await client.createKey(keyName, "RSA", {
  enabled: false,
});
console.log("result: ", result);

這會建立相同機碼的新版本,其會具有最新的提供屬性。

屬性也可以更新為具有 updateKeyProperties的現有金鑰版本,如下所示:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

const result = await client.createKey(keyName, "RSA");
await client.updateKeyProperties(keyName, result.properties.version, {
  enabled: false,
});

刪除金鑰

beginDeleteKey 方法會開始刪除金鑰。 只要有必要的資源可供使用,此程式就會在背景進行。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

const poller = await client.beginDeleteKey(keyName);
await poller.pollUntilDone();

如果金鑰保存庫已啟用虛刪除 ,此作業只會將密鑰標示為已刪除 金鑰。 無法更新已刪除的金鑰。 它們只能讀取、復原或清除。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

const poller = await client.beginDeleteKey(keyName);

// You can use the deleted key immediately:
const deletedKey = poller.getResult();

// The key is being deleted. Only wait for it if you want to restore it or purge it.
await poller.pollUntilDone();

// You can also get the deleted key this way:
await client.getDeletedKey(keyName);

// Deleted keys can also be recovered or purged:

// recoverDeletedKey also returns a poller, just like beginDeleteKey.
const recoverPoller = await client.beginRecoverDeletedKey(keyName);
await recoverPoller.pollUntilDone();

// And here is how to purge a deleted key
await client.purgeDeletedKey(keyName);

由於密鑰需要一些時間才能完全刪除,beginDeleteKey 會傳回 Poller 物件,以根據我們的指導方針來追蹤基礎長時間執行作業:https://azure.github.io/azure-sdk/typescript_design.html#ts-lro

收到的輪詢器可讓您呼叫 poller.getResult()來取得已刪除的密鑰。 您也可以等到刪除完成,方法是執行個別服務呼叫,直到刪除金鑰為止,或等到程式完成為止:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

const poller = await client.beginDeleteKey(keyName);

// You can use the deleted key immediately:
let deletedKey = poller.getResult();

// Or you can wait until the key finishes being deleted:
deletedKey = await poller.pollUntilDone();
console.log(deletedKey);

等候金鑰完全刪除的另一種方式是執行個別呼叫,如下所示:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const poller = await client.beginDeleteKey(keyName);

while (!poller.isDone()) {
  await poller.poll();
  await delay(5000);
}

console.log(`The key ${keyName} is fully deleted`);

設定自動金鑰輪替

使用 KeyClient,您可以藉由指定輪替原則來設定密鑰的自動密鑰輪替。 此外,KeyClient 還提供方法,藉由建立新版本的指定密鑰來隨選輪替密鑰。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

// Set the key's automated rotation policy to rotate the key 30 days before expiry.
const policy = await client.updateKeyRotationPolicy(keyName, {
  lifetimeActions: [
    {
      action: "Rotate",
      timeBeforeExpiry: "P30D",
    },
  ],
  // You may also specify the duration after which any newly rotated key will expire.
  // In this case, any new key versions will expire after 90 days.
  expiresIn: "P90D",
});

// You can get the current key rotation policy of a given key by calling the getKeyRotationPolicy method.
const currentPolicy = await client.getKeyRotationPolicy(keyName);

// Finally, you can rotate a key on-demand by creating a new version of the given key.
const rotatedKey = await client.rotateKey(keyName);

反覆運算索引鍵清單

使用 KeyClient,您可以擷取並逐一查看 Azure Key Vault 中的所有金鑰,以及透過所有已刪除的金鑰和特定金鑰的版本。 下列 API 方法可供使用:

  • listPropertiesOfKeys 會依其名稱列出所有未刪除的索引鍵,只列出其最新版本。
  • listDeletedKeys 會依其名稱列出您所有已刪除的金鑰,但只會在最新版本中列出。
  • listPropertiesOfKeyVersions 會根據金鑰名稱列出金鑰的所有版本。

這可以如下所示使用:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

for await (const keyProperties of client.listPropertiesOfKeys()) {
  console.log("Key properties: ", keyProperties);
}

for await (const deletedKey of client.listDeletedKeys()) {
  console.log("Deleted: ", deletedKey);
}

for await (const versionProperties of client.listPropertiesOfKeyVersions(keyName)) {
  console.log("Version properties: ", versionProperties);
}

所有這些方法都會同時傳回所有可用結果 。 若要依頁面擷取它們,請在叫用您想要使用的 API 方法之後,立即新增 .byPage(),如下所示:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const keyName = "MyKeyName";

for await (const page of client.listPropertiesOfKeys().byPage()) {
  for (const keyProperties of page) {
    console.log("Key properties: ", keyProperties);
  }
}

for await (const page of client.listDeletedKeys().byPage()) {
  for (const deletedKey of page) {
    console.log("Deleted key: ", deletedKey);
  }
}

for await (const page of client.listPropertiesOfKeyVersions(keyName).byPage()) {
  for (const versionProperties of page) {
    console.log("Version: ", versionProperties);
  }
}

密碼學

此連結庫也提供一組密碼編譯公用程式,可透過 CryptographyClient取得。 類似於 KeyClientCryptographyClient 會使用提供的認證集連線到 Azure Key Vault。 線上之後,CryptographyClient 可以加密、解密、簽署、驗證、包裝密鑰和解除包裝密鑰。

接下來,我們可以連線到密鑰保存庫服務,就像使用 KeyClient一樣。 我們必須從要連線到的密鑰保存庫複製一些設定,以進入環境變數。 一旦它們位於我們的環境中,我們就可以使用下列程式代碼來存取它們:

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

// Create or retrieve a key from the keyvault
const myKey = await client.createKey("MyKey", "RSA");

// Lastly, create our cryptography client and connect to the service
const cryptographyClient = new CryptographyClient(myKey, credential);

加密

encrypt 會加密訊息。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey.id, credential);

const encryptResult = await cryptographyClient.encrypt({
  algorithm: "RSA1_5",
  plaintext: Buffer.from("My Message"),
});
console.log("encrypt result: ", encryptResult.result);

解密

decrypt 會將加密的訊息解密。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey.id, credential);

const encryptResult = await cryptographyClient.encrypt({
  algorithm: "RSA1_5",
  plaintext: Buffer.from("My Message"),
});
console.log("encrypt result: ", encryptResult.result);

const decryptResult = await cryptographyClient.decrypt({
  algorithm: "RSA1_5",
  ciphertext: encryptResult.result,
});
console.log("decrypt result: ", decryptResult.result.toString());

簽名

sign 會以密碼編譯方式簽署具有簽章之訊息的摘要(哈希)。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";
import { createHash } from "node:crypto";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

let myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey, credential);

const signatureValue = "MySignature";
const hash = createHash("sha256");

const digest = hash.update(signatureValue).digest();
console.log("digest: ", digest);

const signResult = await cryptographyClient.sign("RS256", digest);
console.log("sign result: ", signResult.result);

簽署數據

signData 會以密碼編譯方式簽署具有簽章的訊息。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey, credential);

const signResult = await cryptographyClient.signData("RS256", Buffer.from("My Message"));
console.log("sign result: ", signResult.result);

驗證

verify 會以密碼編譯方式驗證已使用指定簽章簽署的已簽署摘要。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";
import { createHash } from "node:crypto";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey, credential);

const hash = createHash("sha256");
hash.update("My Message");
const digest = hash.digest();

const signResult = await cryptographyClient.sign("RS256", digest);
console.log("sign result: ", signResult.result);

const verifyResult = await cryptographyClient.verify("RS256", digest, signResult.result);
console.log("verify result: ", verifyResult.result);

驗證數據

verifyData 會以密碼編譯方式驗證已簽署的訊息是否已使用指定的簽章簽署。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey, credential);

const buffer = Buffer.from("My Message");

const signResult = await cryptographyClient.signData("RS256", buffer);
console.log("sign result: ", signResult.result);

const verifyResult = await cryptographyClient.verifyData("RS256", buffer, signResult.result);
console.log("verify result: ", verifyResult.result);

包裝金鑰

wrapKey 會將金鑰包裝在加密層。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey, credential);

const wrapResult = await cryptographyClient.wrapKey("RSA-OAEP", Buffer.from("My Key"));
console.log("wrap result:", wrapResult.result);

將金鑰解除包裝

unwrapKey 會解除包裝的密鑰。

import { DefaultAzureCredential } from "@azure/identity";
import { KeyClient, CryptographyClient } from "@azure/keyvault-keys";

const credential = new DefaultAzureCredential();

const vaultName = "<YOUR KEYVAULT NAME>";
const url = `https://${vaultName}.vault.azure.net`;

const client = new KeyClient(url, credential);

const myKey = await client.createKey("MyKey", "RSA");
const cryptographyClient = new CryptographyClient(myKey, credential);

const wrapResult = await cryptographyClient.wrapKey("RSA-OAEP", Buffer.from("My Key"));
console.log("wrap result:", wrapResult.result);

const unwrapResult = await cryptographyClient.unwrapKey("RSA-OAEP", wrapResult.result);
console.log("unwrap result: ", unwrapResult.result);

故障排除

如需如何診斷各種失敗案例的詳細資訊,請參閱我們的 疑難解答指南

啟用記錄可能有助於找出有關失敗的實用資訊。 若要查看 HTTP 要求和回應的記錄,請將 AZURE_LOG_LEVEL 環境變數設定為 info。 或者,您可以在運行時間啟用記錄,方法是在 setLogLevel中呼叫 @azure/logger

import { setLogLevel } from "@azure/logger";

setLogLevel("info");

後續步驟

您可以透過下列連結找到更多程式碼範例:

貢獻

如果您想要參與此連結庫,請閱讀 參與指南,以深入瞭解如何建置和測試程序代碼。