Start · Sprachen · JavaScript · Referenz · Pbkdf2Params

Pbkdf2Params

Schnittstelle

Wörterbuch mit den Parametern für PBKDF2 (<code>name</code>, <code>hash</code>, <code>salt</code>, <code>iterations</code>), das an <code>SubtleCrypto.deriveKey()</code> bzw. <code>deriveBits()</code> übergeben wird.

seit JavaScript Baseline: alle modernen Browser (Web Crypto API), Kategorie: webapi

Signatur

interface Pbkdf2Params extends Algorithm

Beschreibung

Pbkdf2Params ist ein einfaches Wörterbuch (Dictionary) der Web Crypto API, also keine Klasse mit Konstruktor. Es beschreibt, wie der Algorithmus PBKDF2 (Password-Based Key Derivation Function 2, RFC 8018) aus einem Passwort einen kryptografischen Schlüssel ableiten soll. Das Objekt wird als algorithm-Argument an SubtleCrypto.deriveKey() oder SubtleCrypto.deriveBits() übergeben.

Typischerweise wird PBKDF2 eingesetzt, wenn ein Benutzerpasswort in einen symmetrischen Schlüssel umgewandelt werden soll, zum Beispiel für clientseitige Verschlüsselung mit AES-GCM. Der Ablauf ist immer gleich: Zuerst wird das Passwort mit importKey("raw", …, "PBKDF2", false, ["deriveKey"]) als Basisschlüssel importiert. Danach leitet deriveKey() mit einem Pbkdf2Params-Objekt den eigentlichen Schlüssel ab.

Wie sicher das Ergebnis ist, hängt vor allem von zwei Dingen ab: einem zufälligen, pro Passwort eindeutigen Salt und einer hohen Iterationszahl. Beide Werte sind nicht geheim. Sie müssen aber zusammen mit den verschlüsselten Daten gespeichert werden, sonst lässt sich derselbe Schlüssel später nicht erneut ableiten.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Muss "PBKDF2" sein.
$hash Pflicht string | { name: string } Hash-Funktion für die interne HMAC-Berechnung: "SHA-256", "SHA-384" oder "SHA-512". "SHA-1" ist technisch erlaubt, wird aber nicht empfohlen.
$salt Pflicht ArrayBuffer | TypedArray | DataView Zufälliger Salt, mindestens 16 Byte lang. Am besten mit crypto.getRandomValues(new Uint8Array(16)) erzeugen. Er muss nicht geheim bleiben, aber für jedes Passwort eindeutig sein.
$iterations Pflicht number Anzahl der Iterationen. OWASP empfiehlt (Stand 2023) mindestens 600000 bei SHA-256 bzw. 210000 bei SHA-512.

Rückgabewert

Typ
Pbkdf2Params
Beschreibung
Ein einfaches Objekt, das als algorithm-Argument an deriveKey() oder deriveBits() übergeben wird. Es hat keinen eigenen Rückgabewert.

Beispiele

AES-GCM-Schlüssel aus einem Passwort ableiten

const deriveAesKey = async (password, salt) => {
  const enc = new TextEncoder();
  // Passwort als Basisschlüssel importieren
  const baseKey = await crypto.subtle.importKey(
    'raw', enc.encode(password), 'PBKDF2', false, ['deriveKey']
  );

  /** @type {Pbkdf2Params} */
  const params = {
    name: 'PBKDF2',
    hash: 'SHA-256',
    salt,
    iterations: 600_000
  };

  return crypto.subtle.deriveKey(
    params,
    baseKey,
    { name: 'AES-GCM', length: 256 },
    false,
    ['encrypt', 'decrypt']
  );
};

const salt = crypto.getRandomValues(new Uint8Array(16));
const key = await deriveAesKey('geheim123', salt);
console.log(key.algorithm);
{ name: 'AES-GCM', length: 256 }

Text verschlüsseln, Salt und IV mitspeichern

const encryptText = async (password, text) => {
  const enc = new TextEncoder();
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const baseKey = await crypto.subtle.importKey('raw', enc.encode(password), 'PBKDF2', false, ['deriveKey']);
  const key = await crypto.subtle.deriveKey(
    { name: 'PBKDF2', hash: 'SHA-256', salt, iterations: 600_000 },
    baseKey,
    { name: 'AES-GCM', length: 256 },
    false,
    ['encrypt']
  );
  const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, enc.encode(text));
  // Salt, IV und Iterationszahl werden zum Entschlüsseln gebraucht
  return { salt, iv, iterations: 600_000, ciphertext: new Uint8Array(ciphertext) };
};

const result = await encryptText('geheim123', 'Hallo Welt');
console.log(result.salt.length, result.iv.length);
16 12

Rohe Bits mit deriveBits() erzeugen

const enc = new TextEncoder();
const baseKey = await crypto.subtle.importKey('raw', enc.encode('passwort'), 'PBKDF2', false, ['deriveBits']);
const bits = await crypto.subtle.deriveBits(
  { name: 'PBKDF2', hash: 'SHA-512', salt: enc.encode('fester-salt-nur-demo'), iterations: 210_000 },
  baseKey,
  256
);
const hex = [...new Uint8Array(bits)].map(b => b.toString(16).padStart(2, '0')).join('');
console.log(hex.length);
64

// Wichtig · Fallstricke

  • Kein fester Salt: Ein fester oder vorhersehbarer Salt macht Angriffe mit vorberechneten Tabellen (Rainbow Tables) möglich. Erzeuge den Salt deshalb immer mit crypto.getRandomValues(). Der feste Salt in Beispiel 3 dient nur der Demonstration.
  • Iterationszahl: Niedrige Werte wie 1000 aus älteren Anleitungen sind heute unsicher. Speichere die Iterationszahl zusammen mit den Daten. Dann kannst du sie später erhöhen, ohne bestehende Daten unlesbar zu machen.
  • Basisschlüssel: Der Basisschlüssel muss mit dem Algorithmus "PBKDF2" und extractable: false importiert werden. Außerdem braucht er die passende Verwendung (deriveKey oder deriveBits).
  • Serverseitige Passwortspeicherung: PBKDF2 ist GPU-freundlich. Für das Speichern von Passwörtern auf dem Server sind speicherintensive Verfahren wie Argon2 oder scrypt besser geeignet. Diese bietet die Web Crypto API allerdings nicht an.
  • Kompatibilität: crypto.subtle ist nur in sicheren Kontexten (HTTPS oder localhost) verfügbar. Unterstützt wird es von allen modernen Browsern sowie von Node.js ab Version 15 (über require('crypto').webcrypto, global ab Version 19). Bei iterations: 0 wird die Operation mit einem OperationError abgelehnt.