SubtleCrypto: deriveBits() 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 deriveBits()
-Methode der
SubtleCrypto
-Schnittstelle kann verwendet werden, um ein Array von Bits aus einem Basisschlüssel abzuleiten.
Sie nimmt als Argumente den Basisschlüssel, den zu verwendenden Ableitungsalgorithmus und die Länge der abzuleitenden Bits. Sie gibt ein Promise
zurück, das mit einem ArrayBuffer
erfüllt wird, der die abgeleiteten Bits enthält.
Diese Methode ist der
SubtleCrypto.deriveKey()
-Methode sehr ähnlich, mit dem Unterschied, dass deriveKey()
ein
CryptoKey
-Objekt anstelle eines
ArrayBuffer
zurückgibt. Im Wesentlichen setzt sich deriveKey()
aus
deriveBits()
gefolgt von
importKey()
zusammen.
Diese Funktion unterstützt die gleichen Ableitungsalgorithmen wie deriveKey()
: ECDH, HKDF, PBKDF2 und X25519.
Siehe Unterstützte Algorithmen für weitere Details zu diesen Algorithmen.
Syntax
deriveBits(algorithm, baseKey, length)
Parameter
algorithm
-
Ein Objekt, das den zu verwendenden Ableitungsalgorithmus definiert.
- Um ECDH zu verwenden, übergeben Sie ein
EcdhKeyDeriveParams
-Objekt und geben Sie den StringECDH
alsname
-Eigenschaft an. - Um HKDF zu verwenden, übergeben Sie ein
HkdfParams
-Objekt. - Um PBKDF2 zu verwenden, übergeben Sie ein
Pbkdf2Params
-Objekt. - Um X25519 zu verwenden, übergeben Sie ein
EcdhKeyDeriveParams
-Objekt und geben Sie den StringX25519
alsname
-Eigenschaft an.
- Um ECDH zu verwenden, übergeben Sie ein
baseKey
-
Ein
CryptoKey
, der die Eingabe für den Ableitungsalgorithmus darstellt. Wennalgorithm
ECDH ist, handelt es sich um den ECDH-Privatschlüssel. Andernfalls ist es das Ausgangsschlüsselmaterial für die Ableitungsfunktion: Beispielsweise könnte es sich bei PBKDF2 um ein Passwort handeln, das alsCryptoKey
mithilfe vonSubtleCrypto.importKey()
importiert wurde. length
-
Eine Zahl, die die Anzahl der abzuleitenden Bits repräsentiert. Um mit allen Browsern kompatibel zu sein, sollte die Zahl ein Vielfaches von 8 sein.
Rückgabewert
Ein Promise
, das mit einem ArrayBuffer
erfüllt wird, der die abgeleiteten Bits enthält.
Ausnahmen
Das Promise wird abgelehnt, wenn eine der folgenden Ausnahmen auftritt:
OperationError
DOMException
-
Wird ausgelöst, wenn der length-Parameter des
deriveBits()
-Aufrufs null ist und auch in einigen Fällen, wenn der length-Parameter kein Vielfaches von 8 ist. InvalidAccessError
DOMException
-
Wird ausgelöst, wenn der Basisschlüssel kein Schlüssel für den angeforderten Ableitungsalgorithmus ist oder wenn der
CryptoKey.usages
-Wert dieses Schlüssels nichtderiveBits
enthält. NotSupported
DOMException
-
Wird ausgelöst, wenn versucht wird, einen Algorithmus zu verwenden, der entweder unbekannt ist oder nicht für die Ableitung geeignet ist.
Unterstützte Algorithmen
Beispiele
Hinweis: Sie können die funktionierenden Beispiele auf GitHub ausprobieren.
ECDH
In diesem Beispiel generieren Alice und Bob jeweils ein ECDH-Schlüsselpaar.
Wir verwenden dann Alices privaten Schlüssel und Bobs öffentlichen Schlüssel, um ein gemeinsames Geheimnis abzuleiten. Sehen Sie den vollständigen Code auf GitHub.
async function deriveSharedSecret(privateKey, publicKey) {
const sharedSecret = await window.crypto.subtle.deriveBits(
{
name: "ECDH",
namedCurve: "P-384",
public: publicKey,
},
privateKey,
128,
);
const buffer = new Uint8Array(sharedSecret, 0, 5);
const sharedSecretValue = document.querySelector(".ecdh .derived-bits-value");
sharedSecretValue.classList.add("fade-in");
sharedSecretValue.addEventListener("animationend", () => {
sharedSecretValue.classList.remove("fade-in");
});
sharedSecretValue.textContent = `${buffer}…[${sharedSecret.byteLength} bytes total]`;
}
// 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
const generateAliceKeyPair = window.crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384",
},
false,
["deriveBits"],
);
const generateBobKeyPair = window.crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-384",
},
false,
["deriveBits"],
);
Promise.all([generateAliceKeyPair, generateBobKeyPair]).then((values) => {
const aliceKeyPair = values[0];
const bobKeyPair = values[1];
const deriveBitsButton = document.querySelector(".ecdh .derive-bits-button");
deriveBitsButton.addEventListener("click", () => {
// Alice then generates a secret using her private key and Bob's public key.
// Bob could generate the same secret using his private key and Alice's public key.
deriveSharedSecret(aliceKeyPair.privateKey, bobKeyPair.publicKey);
});
});
X25519
In diesem Beispiel generieren Alice und Bob jeweils ein X25519-Schlüsselpaar. Wir verwenden dann Alices privaten Schlüssel und Bobs öffentlichen Schlüssel, um ein Geheimnis abzuleiten, und vergleichen dies mit dem Geheimnis, das mit Bobs privatem Schlüssel und Alices öffentlichem Schlüssel generiert wurde, um zu zeigen, dass sie identisch sind.
HTML
Das HTML definiert zwei Schaltflächen. Die "Change keys"-Schaltfläche wird gedrückt, um neue Schlüsselpaare für Alice und Bob zu generieren. Die "Derive bits"-Schaltfläche wird gedrückt, um ein gemeinsames Geheimnis mit dem aktuellen Satz von Schlüsselpaaren abzuleiten.
<input id="buttonDeriveKeys" type="button" value="Derive bits" />
<input id="buttonChangeKeys" type="button" value="Change keys" />
JavaScript
Die Funktion zum Generieren eines gemeinsamen Geheimnisses unter Verwendung des X25519-Algorithmus wird unten angezeigt. Diese nimmt einen privaten Schlüssel von einer Partei und den öffentlichen Schlüssel von einer anderen.
async function deriveSharedSecret(privateKey, publicKey) {
return await window.crypto.subtle.deriveBits(
{
name: "X25519",
public: publicKey,
},
privateKey,
128,
);
}
Der folgende Code fügt eine Funktion hinzu, um neue Schlüssel für Alice und Bob zu generieren. Dies wird beim ersten Laden des JavaScripts durchgeführt und immer wiederholt, wenn die "Change keys"-Schaltfläche gedrückt wird (dies ermöglicht es uns, die Auswirkungen des Änderns der Schlüssel auf das gemeinsame Geheimnis zu sehen).
let aliceKeyPair;
let bobKeyPair;
async function changeKeys() {
try {
aliceKeyPair = await window.crypto.subtle.generateKey(
{
name: "X25519",
},
false,
["deriveBits"],
);
bobKeyPair = await window.crypto.subtle.generateKey(
{
name: "X25519",
},
false,
["deriveBits"],
);
log("Keys changed");
} catch (e) {
log(e);
}
}
changeKeys();
const changeKeysButton = document.querySelector("#buttonChangeKeys");
// Generate 2 X25519 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
changeKeysButton.addEventListener("click", changeKeys);
Der folgende Code fügt eine Handler-Funktion hinzu, die jedes Mal aufgerufen wird, wenn die "Derive bits"-Schaltfläche gedrückt wird.
Der Handler generiert die gemeinsamen Geheimnisse für Alice und Bob mithilfe der oben definierten deriveSharedSecret()
-Methode und protokolliert sie, um den Vergleich zu erleichtern.
const deriveBitsButton = document.querySelector("#buttonDeriveKeys");
deriveBitsButton.addEventListener("click", async () => {
// Generate 2 X25519 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
// Alice then generates a secret using her private key and Bob's public key.
// Bob could generate the same secret using his private key and Alice's public key.
const sharedSecretAlice = await deriveSharedSecret(
aliceKeyPair.privateKey,
bobKeyPair.publicKey,
);
let buffer = new Uint8Array(sharedSecretAlice, 0, 10);
log(`${buffer}…[${sharedSecretAlice.byteLength} bytes total] (Alice secret)`);
const sharedSecretBob = await deriveSharedSecret(
bobKeyPair.privateKey,
aliceKeyPair.publicKey,
);
buffer = new Uint8Array(sharedSecretBob, 0, 10);
log(`${buffer}…[${sharedSecretAlice.byteLength} bytes total] (Bob secret)`);
});
Ergebnis
Drücken Sie die "Derive bits"-Schaltfläche, um ein gemeinsames Geheimnis aus Bobs und Alices Schlüsseln zu generieren und zu protokollieren. Drücken Sie die "Change keys"-Schaltfläche, um die von beiden Parteien verwendeten X25519-Schlüssel zu ändern.
PBKDF2
In diesem Beispiel fragen wir den Benutzer nach einem Passwort und verwenden es dann, um einige Bits mit PBKDF2 abzuleiten. Sehen Sie den vollständigen Code auf GitHub.
let salt;
/*
Get some key material to use as input to the deriveBits 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"],
);
}
/*
Derive some bits from a password supplied by the user.
*/
async function getDerivedBits() {
const keyMaterial = await getKeyMaterial();
salt = window.crypto.getRandomValues(new Uint8Array(16));
const derivedBits = await window.crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
256,
);
const buffer = new Uint8Array(derivedBits, 0, 5);
const derivedBitsValue = document.querySelector(
".pbkdf2 .derived-bits-value",
);
derivedBitsValue.classList.add("fade-in");
derivedBitsValue.addEventListener("animationend", () => {
derivedBitsValue.classList.remove("fade-in");
});
derivedBitsValue.textContent = `${buffer}…[${derivedBits.byteLength} bytes total]`;
}
const deriveBitsButton = document.querySelector(".pbkdf2 .derive-bits-button");
deriveBitsButton.addEventListener("click", () => {
getDerivedBits();
});
Spezifikationen
Specification |
---|
Web Cryptography API # SubtleCrypto-method-deriveBits |
Browser-Kompatibilität
BCD tables only load in the browser