SubtleCrypto: wrapKey() Methode
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.
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Hinweis: Diese Funktion ist in Web Workers verfügbar.
Die wrapKey()
-Methode des SubtleCrypto
-Interfaces „umhüllt“ einen Schlüssel. Das bedeutet, dass der Schlüssel in einem externen, portablen Format exportiert und anschließend verschlüsselt wird. Das Umhüllen eines Schlüssels hilft, ihn in nicht vertrauenswürdigen Umgebungen zu schützen, wie z.B. in einem ansonsten ungeschützten Datenspeicher oder bei der Übertragung über ein ungeschütztes Netzwerk.
Wie bei SubtleCrypto.exportKey()
geben Sie ein Exportformat für den Schlüssel an. Um einen Schlüssel zu exportieren, muss CryptoKey.extractable
auf true
gesetzt sein.
Da wrapKey()
den zu exportierenden Schlüssel verschlüsselt, müssen Sie auch den Schlüssel angeben, der zur Verschlüsselung verwendet werden soll. Dieser wird manchmal als „Verpackungsschlüssel“ bezeichnet.
Das Gegenteil von wrapKey()
ist SubtleCrypto.unwrapKey()
: Während wrapKey
aus Export + Verschlüsselung besteht, besteht unwrapKey
aus Import + Entschlüsselung.
Syntax
wrapKey(format, key, wrappingKey, wrapAlgo)
Parameter
format
-
Ein Zeichenfolgewert, der das Datenformat beschreibt, in dem der Schlüssel exportiert wird, bevor er verschlüsselt wird. Es kann eines der folgenden sein:
raw
-
Roh Format.
pkcs8
-
PKCS #8 Format.
spki
-
SubjectPublicKeyInfo Format.
jwk
-
JSON Web Key Format.
key
-
Der zu umhüllende
CryptoKey
. wrappingkey
-
Der
CryptoKey
, der zum Verschlüsseln des exportierten Schlüssels verwendet wird. Der Schlüssel muss die VerwendungwrapKey
haben. wrapAlgo
-
Ein Objekt, das den zu verwendenden Algorithmus zur Verschlüsselung des exportierten Schlüssels und alle erforderlichen zusätzlichen Parameter spezifiziert:
- Um RSA-OAEP zu verwenden,
geben Sie ein
RsaOaepParams
-Objekt an. - Um AES-CTR zu verwenden,
geben Sie ein
AesCtrParams
-Objekt an. - Um AES-CBC zu verwenden,
geben Sie ein
AesCbcParams
-Objekt an. - Um AES-GCM zu verwenden,
geben Sie ein
AesGcmParams
-Objekt an. - Um AES-KW zu verwenden,
geben Sie die Zeichenfolge
"AES-KW"
oder ein Objekt der Form{ name: "AES-KW" }
an.
- Um RSA-OAEP zu verwenden,
geben Sie ein
Rückgabewert
Ein Promise
, das mit einem ArrayBuffer
erfüllt wird, der den verschlüsselten exportierten Schlüssel enthält.
Ausnahmen
Das Promise wird abgelehnt, wenn eine der folgenden Ausnahmen auftritt:
InvalidAccessError
DOMException
-
Wird ausgelöst, wenn der Verpackungsschlüssel nicht für den angeforderten Umhüllungsalgorithmus geeignet ist.
NotSupported
DOMException
-
Wird ausgelöst, wenn versucht wird, einen unbekannten oder für Verschlüsselung oder Umhüllung ungeeigneten Algorithmus zu verwenden.
TypeError
-
Wird ausgelöst, wenn versucht wird, ein ungültiges Format zu verwenden.
Unterstützte Algorithmen
Alle Algorithmen, die für die Verschlüsselung verwendet werden können, können auch für die Schlüsselumhüllung verwendet werden, solange der Schlüssel die Verwendung "wrapKey" hat. Für die Schlüsselumhüllung haben Sie die zusätzliche Option von AES-KW.
AES-KW
AES-KW ist eine Möglichkeit, das AES-Cipher für die Schlüsselumhüllung zu verwenden.
Ein Vorteil von AES-KW gegenüber anderen AES-Modi wie AES-GCM ist, dass AES-KW keinen Initialisierungsvektor benötigt. Um AES-KW zu verwenden, muss die Eingabe ein Vielfaches von 64 Bits sein.
AES-KW ist in RFC 3394 spezifiziert.
Beispiele
Hinweis: Sie können die funktionierenden Beispiele auf GitHub ausprobieren.
Rohumhüllung
Dieses Beispiel umhüllt einen AES-Schlüssel. Es verwendet "raw" als Exportformat und AES-KW mit einem passwortabgeleiteten Schlüssel, um ihn zu verschlüsseln. Sehen Sie den vollständigen Code auf GitHub.
let salt;
/*
Get some key material to use as input to the deriveKey method.
The key material is a password supplied by the user.
*/
function getKeyMaterial() {
const password = window.prompt("Enter your password");
const enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"],
);
}
/*
Given some key material and some random salt
derive an AES-KW key using PBKDF2.
*/
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
{ name: "AES-KW", length: 256 },
true,
["wrapKey", "unwrapKey"],
);
}
/*
Wrap the given key.
*/
async function wrapCryptoKey(keyToWrap) {
// get the key encryption key
const keyMaterial = await getKeyMaterial();
salt = window.crypto.getRandomValues(new Uint8Array(16));
const wrappingKey = await getKey(keyMaterial, salt);
return window.crypto.subtle.wrapKey("raw", keyToWrap, wrappingKey, "AES-KW");
}
/*
Generate an encrypt/decrypt secret key,
then wrap it.
*/
window.crypto.subtle
.generateKey(
{
name: "AES-GCM",
length: 256,
},
true,
["encrypt", "decrypt"],
)
.then((secretKey) => wrapCryptoKey(secretKey))
.then((wrappedKey) => console.log(wrappedKey));
PKCS #8 Umhüllung
Dieses Beispiel umhüllt einen RSA-privaten Signaturschlüssel. Es verwendet "pkcs8" als Exportformat und AES-GCM mit einem passwortabgeleiteten Schlüssel, um ihn zu verschlüsseln. Sehen Sie den vollständigen Code auf GitHub.
let salt;
let iv;
/*
Get some key material to use as input to the deriveKey method.
The key material is a password supplied by the user.
*/
function getKeyMaterial() {
const password = window.prompt("Enter your password");
const enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"],
);
}
/*
Given some key material and some random salt
derive an AES-GCM key using PBKDF2.
*/
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
{ name: "AES-GCM", length: 256 },
true,
["wrapKey", "unwrapKey"],
);
}
/*
Wrap the given key.
*/
async function wrapCryptoKey(keyToWrap) {
// get the key encryption key
const keyMaterial = await getKeyMaterial();
salt = window.crypto.getRandomValues(new Uint8Array(16));
const wrappingKey = await getKey(keyMaterial, salt);
iv = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.wrapKey("pkcs8", keyToWrap, wrappingKey, {
name: "AES-GCM",
iv,
});
}
/*
Generate a sign/verify key pair,
then wrap the private key.
*/
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) => wrapCryptoKey(keyPair.privateKey))
.then((wrappedKey) => {
console.log(wrappedKey);
});
SubjectPublicKeyInfo Umhüllung
Dieses Beispiel umhüllt einen RSA-öffentlichen Verschlüsselungsschlüssel. Es verwendet "spki" als Exportformat und AES-CBC mit einem passwortabgeleiteten Schlüssel, um ihn zu verschlüsseln. Sehen Sie den vollständigen Code auf GitHub.
let salt;
let iv;
/*
Get some key material to use as input to the deriveKey method.
The key material is a password supplied by the user.
*/
function getKeyMaterial() {
const password = window.prompt("Enter your password");
const enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"],
);
}
/*
Given some key material and some random salt
derive an AES-CBC key using PBKDF2.
*/
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
{ name: "AES-CBC", length: 256 },
true,
["wrapKey", "unwrapKey"],
);
}
/*
Wrap the given key.
*/
async function wrapCryptoKey(keyToWrap) {
// get the key encryption key
const keyMaterial = await getKeyMaterial();
salt = window.crypto.getRandomValues(new Uint8Array(16));
const wrappingKey = await getKey(keyMaterial, salt);
iv = window.crypto.getRandomValues(new Uint8Array(16));
return window.crypto.subtle.wrapKey("spki", keyToWrap, wrappingKey, {
name: "AES-CBC",
iv,
});
}
/*
Generate an encrypt/decrypt key pair,
then wrap it.
*/
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) => wrapCryptoKey(keyPair.publicKey))
.then((wrappedKey) => console.log(wrappedKey));
JSON Web Key Umhüllung
Dieses Beispiel umhüllt einen ECDSA-privaten Signaturschlüssel. Es verwendet "jwk" als Exportformat und AES-GCM mit einem passwortabgeleiteten Schlüssel, um ihn zu verschlüsseln. Sehen Sie den vollständigen Code auf GitHub.
let salt;
let iv;
/*
Get some key material to use as input to the deriveKey method.
The key material is a password supplied by the user.
*/
function getKeyMaterial() {
const password = window.prompt("Enter your password");
const enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"],
);
}
/*
Given some key material and some random salt
derive an AES-GCM key using PBKDF2.
*/
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
{ name: "AES-GCM", length: 256 },
true,
["wrapKey", "unwrapKey"],
);
}
/*
Wrap the given key.
*/
async function wrapCryptoKey(keyToWrap) {
// get the key encryption key
const keyMaterial = await getKeyMaterial();
salt = window.crypto.getRandomValues(new Uint8Array(16));
const wrappingKey = await getKey(keyMaterial, salt);
iv = window.crypto.getRandomValues(new Uint8Array(12));
return window.crypto.subtle.wrapKey("jwk", keyToWrap, wrappingKey, {
name: "AES-GCM",
iv,
});
}
/*
Generate a sign/verify key pair,
then wrap the private key
*/
window.crypto.subtle
.generateKey(
{
name: "ECDSA",
namedCurve: "P-384",
},
true,
["sign", "verify"],
)
.then((keyPair) => wrapCryptoKey(keyPair.privateKey))
.then((wrappedKey) => console.log(wrappedKey));
Spezifikationen
Specification |
---|
Web Cryptography API # SubtleCrypto-method-wrapKey |
Browser-Kompatibilität
BCD tables only load in the browser