SubtleCrypto: importKey() 方法
Baseline 廣泛可用 *
注意:此功能在 Web Workers 中可用。
SubtleCrypto 介面的 importKey() 方法用於匯入金鑰。也就是說,它接受一個外部、可移植格式的金鑰作為輸入,並返回一個您可以在 Web Crypto API 中使用的 CryptoKey 物件。
該函式接受多種匯入格式:有關詳細資訊,請參閱 支援的格式。
語法
importKey(format, keyData, algorithm, extractable, keyUsages)
引數
格式(format)-
一個描述要匯入的金鑰資料格式的字串。它可以是以下之一:
raw: 原始格式。pkcs8: PKCS #8 格式。spki: SubjectPublicKeyInfo 格式。jwk: JSON Web Key 格式。
keyData-
一個包含給定格式金鑰的
ArrayBuffer、TypedArray、DataView或JSONWebKey物件。 algorithm-
一個定義要匯入的金鑰型別並提供其他特定於演算法的引數的物件。
- 對於 RSASSA-PKCS1-v1_5、RSA-PSS 或 RSA-OAEP:傳遞一個
RsaHashedImportParams物件。 - 對於 ECDSA 或 ECDH:傳遞一個
EcKeyImportParams物件。 - 對於 HMAC:傳遞一個
HmacImportParams物件。 - 對於 AES-CTR、AES-CBC、AES-GCM 和 AES-KW:傳遞標識演算法的字串或形式為
{ name: ALGORITHM }的物件,其中ALGORITHM是演算法的名稱。 - 對於 PBKDF2:傳遞字串
PBKDF2或形式為{ name: "PBKDF2" }的物件。 - 對於 HKDF:傳遞字串
HKDF或形式為{ name: "HKDF" }的物件。 - 對於 Ed25519:傳遞字串
Ed25519或形式為{ name: "Ed25519" }的物件。 - 對於 X25519:傳遞字串
X25519或形式為{ name: "X25519" }的物件。
- 對於 RSASSA-PKCS1-v1_5、RSA-PSS 或 RSA-OAEP:傳遞一個
extractable-
一個布林值,指示是否可以使用
SubtleCrypto.exportKey()或SubtleCrypto.wrapKey()匯出金鑰。 keyUsages-
一個指示金鑰可用於何種操作的
Array。可能的陣列值包括:
返回值
異常
當遇到以下任一異常時,Promise 將被拒絕:
SyntaxErrorDOMException-
當
keyUsages為空,但解封裝的金鑰型別為secret或private時丟擲。 TypeError-
嘗試使用無效格式或
keyData不適合該格式時引發。
支援的格式
此 API 支援四種不同的金鑰匯入/匯出格式:Raw、PKCS #8、SubjectPublicKeyInfo 和 JSON Web Key。
原始格式
您可以使用此格式匯入或匯出 AES 或 HMAC 金鑰,或橢圓曲線公鑰。
在此格式下,金鑰作為包含金鑰原始位元組的 ArrayBuffer 提供。
PKCS #8
您可以使用此格式匯入或匯出 RSA 或橢圓曲線私鑰。
PKCS #8 格式在 RFC 5208 中定義,使用 ASN.1 標記法。
PrivateKeyInfo ::= SEQUENCE {
version Version,
privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
privateKey PrivateKey,
attributes [0] IMPLICIT Attributes OPTIONAL }
importKey() 方法期望接收此物件作為 ArrayBuffer,其中包含 PrivateKeyInfo 的 DER 編碼形式。DER 是一組用於將 ASN.1 結構編碼為二進位制形式的規則。
您最有可能在 PEM 格式中遇到此物件。PEM 格式是一種在 ASCII 中編碼二進位制資料的方法。它由一個頭部和一個尾部組成,中間是 base64 編碼的二進位制資料。PEM 編碼的 PrivateKeyInfo 看起來像這樣:
-----BEGIN PRIVATE KEY----- MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAU9BD0jxDfF5OV380z 9VIEUN2W5kJDZ3hbuaDenCxLiAMsoquKTfFaou71eLdN0TShZANiAARMUhCee/cp xmjGc1roj0D0k6VlUqtA+JVCWigXcIAukOeTHCngZDKCrD4PkXDBvbciJdZKvO+l ml2FIkoovZh/8yeTKmjUMb804g6OmjUc9vVojCRV0YdaSmYkkJMJbLg= -----END PRIVATE KEY-----
要將其轉換為可以傳遞給 importKey() 的格式,您需要執行兩項操作:
- 使用
Window.atob()對頭部和尾部之間的部分進行 base64 解碼。 - 將生成的字串轉換為
ArrayBuffer。
有關更具體的指導,請參閱 示例 部分。
SubjectPublicKeyInfo
您可以使用此格式匯入或匯出 RSA 或橢圓曲線公鑰。
SubjectPublicKey 在 RFC 5280 第 4.1 節中使用 ASN.1 標記法定義。
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
與 PKCS #8 類似,importKey() 方法期望接收此物件作為 ArrayBuffer,其中包含 SubjectPublicKeyInfo 的 DER 編碼形式。
同樣,您最有可能在 PEM 格式中遇到此物件。PEM 編碼的 SubjectPublicKeyInfo 看起來像這樣:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3j+HgSHUnc7F6XzvEbD0 r3M5JNy+/kabiJVu8IU1ERAl3Osi38VgiMzjDBDOrFxVzNNzl+SXAHwXIV5BHiXL CQ6qhwYsDgH6OqgKIwiALra/wNH4UHxj1Or/iyAkjHRR/kGhUtjyVCjzvaQaDpJW 2G+syd1ui0B6kJov2CRUWiPwpff8hBfVWv8q9Yc2yD5hCnykVL0iAiyn+SDAk/rv 8dC5eIlzCI4efUCbyG4c9O88Qz7bS14DxSfaPTy8P/TWoihVVjLaDF743LgM/JLq CDPUBUA3HLsZUhKm3BbSkd7Q9Ngkjv3+yByo4/fL+fkYRa8j9Ypa2N0Iw53LFb3B gQIDAQAB -----END PUBLIC KEY-----
與 PKCS #8 相同,要將其轉換為可以傳遞給 importKey() 的格式,您需要執行兩項操作:
- 使用
Window.atob()對頭部和尾部之間的部分進行 base64 解碼。 - 將生成的字串轉換為
ArrayBuffer。
有關更具體的指導,請參閱 示例 部分。
JSON Web Key
您可以使用 JSON Web Key 格式匯入或匯出 RSA 或橢圓曲線公鑰或私鑰,以及 AES 和 HMAC 金鑰。
JSON Web Key 格式在 RFC 7517 中定義。它描述了一種將公鑰、私鑰和金鑰作為 JSON 物件表示的方法。
JSON Web Key 的外觀大致如下(這是一個 EC 私鑰):
{
"crv": "P-384",
"d": "wouCtU7Nw4E8_7n5C1-xBjB4xqSb_liZhYMsy8MGgxUny6Q8NCoH9xSiviwLFfK_",
"ext": true,
"key_ops": ["sign"],
"kty": "EC",
"x": "SzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQ",
"y": "hHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL-WLKjnGjQAw0rNGy5V29-aV-yseW"
}
示例
注意:您可以 在 GitHub 上嘗試實際示例。
原始格式匯入
此示例從包含原始位元組的 ArrayBuffer 匯入 AES 金鑰以供使用。在 GitHub 上檢視完整程式碼。
const rawKey = window.crypto.getRandomValues(new Uint8Array(16));
/*
Import an AES secret key from an ArrayBuffer containing the raw bytes.
Takes an ArrayBuffer string containing the bytes, and returns a Promise
that will resolve to a CryptoKey representing the secret key.
*/
function importSecretKey(rawKey) {
return window.crypto.subtle.importKey("raw", rawKey, "AES-GCM", true, [
"encrypt",
"decrypt",
]);
}
PKCS #8 格式匯入
此示例從 PEM 編碼的 PKCS #8 物件匯入 RSA 私鑰簽名金鑰。在 GitHub 上檢視完整程式碼。
/*
Convert a string into an ArrayBuffer
from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
*/
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
const pemEncodedKey = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDD0tPV/du2vftjvXj1t/gXTK39sNBVrOAEb/jKzXae+Xa0H+3LhZaQIQNMfACiBSgIfZUvEGb+7TqXWQpoLoFR/R7MvGWcSk98JyrVtveD8ZmZYyItSY7m2hcasqAFiKyOouV5vzyRe87/lEyzzBpF3bQQ4IDaQu+K9Hj5fKuU6rrOeOhsdnJc+VdDQLScHxvMoLZ9Vtt+oK9J4/tOLwr4CG8khDlBURcBY6gPcLo3dPU09SW+6ctX2cX4mkXx6O/0mmdTmacr/vu50KdRMleFeZYOWPAEhhMfywybTuzBiPVIZVP8WFCSKNMbfi1S9A9PdBqnebwwHhX3/hsEBt2BAgMBAAECggEABEI1P6nf6Zs7mJlyBDv+Pfl5rjL2cOqLy6TovvZVblMkCPpJyFuNIPDK2tK2i897ZaXfhPDBIKmllM2Hq6jZQKB110OAnTPDg0JxzMiIHPs32S1d/KilHjGff4Hjd4NXp1l1Dp8BUPOllorR2TYm2x6dcCGFw9lhTr8O03Qp4hjn84VjGIWADYCk83mgS4nRsnHkdiqYnWx1AjKlY51yEK6RcrDMi0Th2RXrrINoC35sVv+APt2rkoMGi52RwTEseA1KZGFrxjq61ReJif6p2VXEcvHeX6CWLx014LGk43z6Q28P6HgeEVEfIjyqCUea5Du/mYb/QsRSCosXLxBqwQKBgQD1+fdC9ZiMrVI+km7Nx2CKBn8rJrDmUh5SbXn2MYJdrUd8bYNnZkCgKMgxVXsvJrbmVOrby2txOiqudZkk5mD3E5O/QZWPWQLgRu8ueYNpobAX9NRgNfZ7rZD+81vh5MfZiXfuZOuzv29iZhU0oqyZ9y75eHkLdrerNkwYOe5aUQKBgQDLzapDi1NxkBgsj9iiO4KUa7jvD4JjRqFy4Zhj/jbQvlvM0F/uFp7sxVcHGx4r11C+6iCbhX4u+Zuu0HGjT4d+hNXmgGyxR8fIUVxOlOtDkVJa5sOBZK73/9/MBeKusdmJPRhalZQfMUJRWIoEVDMhfg3tW/rBj5RYAtP2dTVUMQKBgDs8yr52dRmT+BWXoFWwaWB0NhYHSFz/c8v4D4Ip5DJ5M5kUqquxJWksySGQa40sbqnD05fBQovPLU48hfgr/zghn9hUjBcsoZOvoZR4sRw0UztBvA+7jzOz1hKAOyWIulR6Vca0yUrNlJ6G5R56+sRNkiOETupi2dLCzcqb0PoxAoGAZyNHvTLvIZN4iGSrjz5qkM4LIwBIThFadxbv1fq6pt0O/BGf2o+cEdq0diYlGK64cEVwBwSBnSg4vzlBqRIAUejLjwEDAJyA4EE8Y5A9l04dzV7nJb5cRak6CrgXxay/mBJRFtaHxVlaZGxYPGSYE6UFS0+3EOmmevvDZQBf4qECgYEA0ZF6Vavz28+8wLO6SP3w8NmpHk7K9tGEvUfQ30SgDx4G7qPIgfPrbB4OP/E0qCfsIImi3sCPpjvUMQdVVZyPOIMuB+rV3ZOxkrzxEUOrpOpR48FZbL7RN90yRQsAsrp9e4iv8QwB3VxLe7X0TDqqnRyqrc/osGzuS2ZcHOKmCU8=
-----END PRIVATE KEY-----`;
/*
Import a PEM encoded RSA private key, to use for RSA-PSS signing.
Takes a string containing the PEM encoded key, and returns a Promise
that will resolve to a CryptoKey representing the private key.
*/
function importPrivateKey(pem) {
// fetch the part of the PEM string between header and footer
const pemHeader = "-----BEGIN PRIVATE KEY-----";
const pemFooter = "-----END PRIVATE KEY-----";
const pemContents = pem.substring(
pemHeader.length,
pem.length - pemFooter.length - 1,
);
// base64 decode the string to get the binary data
const binaryDerString = window.atob(pemContents);
// convert from a binary string to an ArrayBuffer
const binaryDer = str2ab(binaryDerString);
return window.crypto.subtle.importKey(
"pkcs8",
binaryDer,
{
name: "RSA-PSS",
hash: "SHA-256",
},
true,
["sign"],
);
}
SubjectPublicKeyInfo 格式匯入
此示例從 PEM 編碼的 SubjectPublicKeyInfo 物件匯入 RSA 公鑰加密金鑰。在 GitHub 上檢視完整程式碼。
// from https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
const pemEncodedKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy3Xo3U13dc+xojwQYWoJLCbOQ5fOVY8LlnqcJm1W1BFtxIhOAJWohiHuIRMctv7dzx47TLlmARSKvTRjd0dF92jx/xY20Lz+DXp8YL5yUWAFgA3XkO3LSJgEOex10NB8jfkmgSb7QIudTVvbbUDfd5fwIBmCtaCwWx7NyeWWDb7A9cFxj7EjRdrDaK3ux/ToMLHFXVLqSL341TkCf4ZQoz96RFPUGPPLOfvN0x66CM1PQCkdhzjE6U5XGE964ZkkYUPPsy6Dcie4obhW4vDjgUmLzv0z7UD010RLIneUgDE2FqBfY/C+uWigNPBPkkQ+Bv/UigS6dHqTCVeD5wgyBQIDAQAB
-----END PUBLIC KEY-----`;
function importRsaKey(pem) {
// fetch the part of the PEM string between header and footer
const pemHeader = "-----BEGIN PUBLIC KEY-----";
const pemFooter = "-----END PUBLIC KEY-----";
const pemContents = pem.substring(
pemHeader.length,
pem.length - pemFooter.length - 1,
);
// base64 decode the string to get the binary data
const binaryDerString = window.atob(pemContents);
// convert from a binary string to an ArrayBuffer
const binaryDer = str2ab(binaryDerString);
return window.crypto.subtle.importKey(
"spki",
binaryDer,
{
name: "RSA-OAEP",
hash: "SHA-256",
},
true,
["encrypt"],
);
}
JSON Web Key 格式匯入
此程式碼匯入 ECDSA 私鑰簽名金鑰,給定一個表示它的 JSON Web Key 物件。在 GitHub 上檢視完整程式碼。
const jwkEcKey = {
crv: "P-384",
d: "wouCtU7Nw4E8_7n5C1-xBjB4xqSb_liZhYMsy8MGgxUny6Q8NCoH9xSiviwLFfK_",
ext: true,
key_ops: ["sign"],
kty: "EC",
x: "SzrRXmyI8VWFJg1dPUNbFcc9jZvjZEfH7ulKI1UkXAltd7RGWrcfFxqyGPcwu6AQ",
y: "hHUag3OvDzEr0uUQND4PXHQTXP5IDGdYhJhL-WLKjnGjQAw0rNGy5V29-aV-yseW",
};
/*
Import a JSON Web Key format EC private key, to use for ECDSA signing.
Takes an object representing the JSON Web Key, and returns a Promise
that will resolve to a CryptoKey representing the private key.
*/
function importPrivateKey(jwk) {
return window.crypto.subtle.importKey(
"jwk",
jwk,
{
name: "ECDSA",
namedCurve: "P-384",
},
true,
["sign"],
);
}
規範
| 規範 |
|---|
| Web 加密級別 2 # SubtleCrypto-method-importKey |
瀏覽器相容性
載入中…