Baseline Widely available *
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 deriveKey()
-Methode der SubtleCrypto
-Schnittstelle kann verwendet werden, um einen geheimen Schlüssel aus einem Master-Schlüssel abzuleiten.
Sie nimmt als Argumente einige anfängliche Schlüsselmaterialien, den zu verwendenden Ableitungsalgorithmus und die gewünschten Eigenschaften für den abzuleitenden Schlüssel. Sie gibt ein Promise
zurück, das mit einem CryptoKey
-Objekt erfüllt wird, das den neuen Schlüssel repräsentiert.
Es ist erwähnenswert, dass die unterstützten Schlüsselableitungsalgorithmen ziemlich unterschiedliche Eigenschaften haben und in verschiedenen Situationen geeignet sind. Weitere Details finden Sie unter Unterstützte Algorithmen.
SyntaxderiveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)
Parameter
algorithm
Ein Objekt, das den zu verwendenden Ableitungsalgorithmus definiert.
EcdhKeyDeriveParams
-Objekt und geben Sie die Zeichenkette ECDH
als name
-Eigenschaft an.HkdfParams
-Objekt.Pbkdf2Params
-Objekt.EcdhKeyDeriveParams
-Objekt und geben Sie die Zeichenkette X25519
als name
-Eigenschaft an.baseKey
Ein CryptoKey
, der den Eingang für den Ableitungsalgorithmus repräsentiert. Wenn algorithm
ECDH oder X25519 ist, dann wird dies der ECDH- oder X25519-Privatschlüssel sein. Andernfalls wird es das anfängliche Schlüsselmaterial für die Ableitungsfunktion sein: zum Beispiel könnte es bei PBKDF2 ein Passwort sein, das als CryptoKey
unter Verwendung von SubtleCrypto.importKey()
importiert wird.
derivedKeyAlgorithm
Ein Objekt, das den Algorithmus definiert, der für den abgeleiteten Schlüssel verwendet werden soll:
HmacKeyGenParams
-Objekt.AesKeyGenParams
-Objekt.HkdfParams
-Objekt.Pbkdf2Params
-Objekt.Ein boolescher Wert, der angibt, ob es möglich sein wird, den Schlüssel mithilfe von SubtleCrypto.exportKey()
oder SubtleCrypto.wrapKey()
zu exportieren.
keyUsages
Ein Array
, das angibt, was mit dem abgeleiteten Schlüssel gemacht werden kann. Beachten Sie, dass die Schlüsselnutzungen vom Algorithmus in derivedKeyAlgorithm
erlaubt sein müssen. Mögliche Werte des Arrays sind:
encrypt
: Der Schlüssel kann verwendet werden, um Nachrichten zu verschlüsseln.decrypt
: Der Schlüssel kann verwendet werden, um Nachrichten zu entschlüsseln.sign
: Der Schlüssel kann verwendet werden, um Nachrichten zu signieren.verify
: Der Schlüssel kann verwendet werden, um Signaturen zu verifizieren.deriveKey
: Der Schlüssel kann zum Ableiten eines neuen Schlüssels verwendet werden.deriveBits
: Der Schlüssel kann zum Ableiten von Bits verwendet werden.wrapKey
: Der Schlüssel kann verwendet werden, um einen Schlüssel zu umwickeln.unwrapKey
: Der Schlüssel kann verwendet werden, um einen Schlüssel zu entpacken.Ein Promise
, das mit einem CryptoKey
erfüllt wird.
Das Promise wird abgelehnt, wenn eine der folgenden Ausnahmen auftritt:
InvalidAccessError
DOMException
Wird ausgelöst, wenn der Master-Schlüssel kein Schlüssel für den angeforderten Ableitungsalgorithmus ist oder wenn der keyUsages
-Wert dieses Schlüssels deriveKey
nicht enthält.
NotSupported
DOMException
Wird ausgelöst, wenn versucht wird, einen Algorithmus zu verwenden, der unbekannt oder für die Ableitung ungeeignet ist, oder wenn der angeforderte Algorithmus für den abgeleiteten Schlüssel keine Schlüssellänge definiert.
SyntaxError
DOMException
Wird ausgelöst, wenn keyUsages
leer ist, der unentpackte Schlüssel jedoch vom Typ secret
oder private
ist.
Die von deriveKey()
unterstützten Algorithmen haben ziemlich unterschiedliche Eigenschaften und eignen sich für unterschiedliche Situationen.
HKDF ist eine Schlüsselableitungsfunktion. Es ist dazu vorgesehen, Schlüsselmaterie aus einer hoch-energiereichen Eingabe abzuleiten, wie zum Beispiel das Ergebnis einer ECDH-Schlüsselvereinbarungsoperation.
Es ist nicht dafür gedacht, Schlüssel aus relativ niedriger ener-gier-reicher Eingabe wie Passwörtern abzuleiten. Dafür verwenden Sie PBKDF2.
HKDF ist in RFC 5869 spezifiziert.
PBKDF2PBKDF2 ist ebenfalls eine Schlüsselableitungsfunktion. Es ist dazu vorgesehen, Schlüsselmaterie aus einer relativ niedriger ener-gier-reicher Eingabe wie einem Passwort abzuleiten. Es leitet Schlüsselmaterie ab, indem es eine Funktion wie HMAC auf das Eingabepasswort zusammen mit etwas Salz anwendet und diesen Prozess viele Male wiederholt. Je häufiger der Prozess wiederholt wird, desto rechnerisch aufwendiger ist die Schlüsselerzeugung: Dies macht es für einen Angreifer schwieriger, den Schlüssel mithilfe eines Wörterbuchangriffs durch brute-force zu entdecken.
PBKDF2 ist in RFC 2898 spezifiziert.
Schlüsselvereinbarungsalgorithmen ECDHECDH (Elliptic Curve DiffieâHellman) ist ein Schlüsselvereinbarungsalgorithmus. Er ermöglicht es zwei Personen, die jeweils ein öffentliches/privates ECDH-Schlüsselpaar haben, ein gemeinsames Geheimnis zu erzeugen: das heiÃt, ein Geheimnis, das sie - und sonst niemand - teilen. Sie können dann dieses gemeinsame Geheimnis als symmetrischen Schlüssel verwenden, um ihre Kommunikation zu sichern, oder das Geheimnis als Eingabe für die Ableitung eines solchen Schlüssels verwenden (zum Beispiel unter Verwendung des HKDF-Algorithmus).
ECDH ist in RFC 6090 spezifiziert.
X25519X25519 ist ein Schlüsselvereinbarungsalgorithmus wie ECDH, basiert jedoch auf der Curve25519-Elliptischen Kurve, die Teil der Edwards-Curve Digital Signature Algorithm (EdDSA)-Algorithmusfamilie ist, die in RFC 8032 definiert ist.
Die Curve25519-Algorithmen werden weit in der Kryptographie verwendet und gelten als einige der effizientesten/schnellsten verfügbaren. Im Vergleich zu den NIST (National Institute of Standards and Technology) Kurven Schlüsselaustauschalgorithmen, die mit ECDH verwendet werden, ist Curve25519 einfacher zu implementieren, und seine nichtstaatliche Herkunft bedeutet, dass die Entscheidungen hinter seinen Designwahl transparent und offen sind.
X25519 ist in RFC 7748 spezifiziert.
BeispieleHinweis: Sie können die funktionierenden Beispiele auf GitHub ausprobieren.
ECDH: gemeinsamer geheimer Schlüssel ableitenIn diesem Beispiel erzeugen Alice und Bob jeweils ein ECDH-Schlüsselpaar und tauschen dann öffentliche Schlüssel aus. AnschlieÃend verwenden sie deriveKey()
, um einen gemeinsamen AES-Schlüssel abzuleiten, den sie verwenden könnten, um Nachrichten zu verschlüsseln. Sehen Sie den vollständigen Code auf GitHub.
/*
Derive an AES key, given:
- our ECDH private key
- their ECDH public key
*/
function deriveSecretKey(privateKey, publicKey) {
return window.crypto.subtle.deriveKey(
{
name: "ECDH",
public: publicKey,
},
privateKey,
{
name: "AES-GCM",
length: 256,
},
false,
["encrypt", "decrypt"],
);
}
async function agreeSharedSecretKey() {
// Generate 2 ECDH key pairs: one for Alice and one for Bob
// In more normal usage, they would generate their key pairs
// separately and exchange public keys securely
let aliceKeyPair = await window.crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384",
},
false,
["deriveKey"],
);
let bobKeyPair = await window.crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384",
},
false,
["deriveKey"],
);
// Alice then generates a secret key using her private key and Bob's public key.
let aliceSecretKey = await deriveSecretKey(
aliceKeyPair.privateKey,
bobKeyPair.publicKey,
);
// Bob generates the same secret key using his private key and Alice's public key.
let bobSecretKey = await deriveSecretKey(
bobKeyPair.privateKey,
aliceKeyPair.publicKey,
);
// Alice can then use her copy of the secret key to encrypt a message to Bob.
let encryptButton = document.querySelector(".ecdh .encrypt-button");
encryptButton.addEventListener("click", () => {
encrypt(aliceSecretKey);
});
// Bob can use his copy to decrypt the message.
let decryptButton = document.querySelector(".ecdh .decrypt-button");
decryptButton.addEventListener("click", () => {
decrypt(bobSecretKey);
});
}
X25519: gemeinsamer geheimer Schlüssel ableiten
In diesem Beispiel erzeugen Alice und Bob jeweils ein X25519-Schlüsselpaar und tauschen dann öffentliche Schlüssel aus. AnschlieÃend verwenden sie jeweils deriveKey()
, um einen gemeinsamen AES-Schlüssel aus ihrem eigenen privaten Schlüssel und dem öffentlichen Schlüssel des anderen abzuleiten. Sie können diesen gemeinsamen Schlüssel für die Verschlüsselung und Entschlüsselung von Nachrichten verwenden, die sie austauschen.
Zuerst definieren wir ein HTML-<input>
, das Sie verwenden, um die Klartextnachricht einzugeben, die "Alice" senden wird, und eine Schaltfläche, die Sie klicken können, um den Verschlüsselungsprozess zu starten.
Dies wird von zwei weiteren Elementen gefolgt, um den Geheimtext anzuzeigen, nachdem Alice den Klartext mit ihrer Kopie des geheimen Schlüssels verschlüsselt hat, und um den Text anzuzeigen, nachdem Bob ihn mit seiner Kopie des geheimen Schlüssels entschlüsselt hat.
JavaScriptDer folgende Code zeigt, wie wir deriveKey()
verwenden. Wir übergeben den X25519-öffentlichen Schlüssel der Gegenpartei, den X25519-Privatschlüssel der lokalen Partei und geben an, dass der abgeleitete Schlüssel ein AES-GCM-Schlüssel sein soll. Wir setzen auch fest, dass der abgeleitete Schlüssel nicht extrahierbar ist und für Verschlüsselung und Entschlüsselung geeignet ist.
Wir verwenden diese Funktion weiter unten im Code, um gemeinsame Schlüssel für Bob und Alice zu erstellen.
Als nächstes definieren wir die Funktionen, die Alice verwenden wird, um ihre Klartextnachricht in UTF-8 zu kodieren und dann zu verschlüsseln, und die Bob verwenden wird, um die Nachricht zu entschlüsseln und dann zu dekodieren. Sie beide nehmen als Argumente den gemeinsamen AES-Schlüssel, einen Initialisierungsvektor und den zu verschlüsselnden oder zu entschlüsselnden Text an.
Der gleiche Initialisierungsvektor muss sowohl für die Verschlüsselung als auch für die Entschlüsselung verwendet werden, aber er muss nicht geheim sein, also wird er normalerweise zusammen mit der verschlüsselten Nachricht gesendet. In diesem Fall, da wir tatsächlich keine Nachricht senden, machen wir ihn einfach direkt verfügbar.
Die Funktion agreeSharedSecretKey()
, die unten dargestellt ist, wird beim Laden aufgerufen, um Paare und gemeinsame Schlüssel für Alice und Bob zu generieren. Sie fügt auch einen Klick-Handler für die "Verschlüsseln"-Schaltfläche hinzu, der die Verschlüsselung und dann die Entschlüsselung des Textes auslöst, der im ersten <input>
definiert ist. Beachten Sie, dass der gesamte Code innerhalb eines try...catch
-Handlers ist, um sicherzustellen, dass wir den Fall protokollieren können, in dem die Schlüsselerstellung fehlschlägt, weil der X25519-Algorithmus nicht unterstützt wird.
Drücken Sie die Schaltfläche Verschlüsseln, um den Text im oberen <input>
-Element zu verschlüsseln und den verschlüsselten Geheimtext und den entschlüsselten Geheimtext in den beiden folgenden Elementen anzuzeigen. Der Protokollbereich am unteren Rand bietet Informationen über die Schlüssel, die vom Code generiert werden.
In diesem Beispiel bitten wir den Benutzer um ein Passwort, verwenden es dann, um einen AES-Schlüssel mithilfe von PBKDF2 abzuleiten, und verwenden dann den AES-Schlüssel, um eine Nachricht zu verschlüsseln. Sehen Sie den vollständigen Code auf GitHub.
/*
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),
"PBKDF2",
false,
["deriveBits", "deriveKey"],
);
}
async function encrypt(plaintext, salt, iv) {
const keyMaterial = await getKeyMaterial();
const key = await window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"],
);
return window.crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, plaintext);
}
HKDF: AES-Schlüssel aus gemeinsamem Geheimnis ableiten
In diesem Beispiel verschlüsseln wir eine Nachricht plainText
gegeben ein gemeinsames Geheimnis secret
, das möglicherweise selbst unter Verwendung eines Algorithmus wie ECDH abgeleitet wurde. Anstatt das gemeinsame Geheimnis direkt zu verwenden, verwenden wir es als Schlüsselmaterie für die HKDF-Funktion, um einen AES-GCM-Verschlüsselungsschlüssel abzuleiten, den wir dann verwenden, um die Nachricht zu verschlüsseln. Sehen Sie den vollständigen Code auf GitHub.
/*
Given some key material and some random salt,
derive an AES-GCM key using HKDF.
*/
function getKey(keyMaterial, salt) {
return window.crypto.subtle.deriveKey(
{
name: "HKDF",
salt,
info: new TextEncoder().encode("Encryption example"),
hash: "SHA-256",
},
keyMaterial,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"],
);
}
async function encrypt(secret, plainText) {
const message = {
salt: window.crypto.getRandomValues(new Uint8Array(16)),
iv: window.crypto.getRandomValues(new Uint8Array(12)),
};
const key = await getKey(secret, message.salt);
message.ciphertext = await window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: message.iv,
},
key,
plainText,
);
return message;
}
Spezifikationen Browser-Kompatibilität Siehe auch
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4