Start · Sprachen · JavaScript · Referenz · AesDerivedKeyParams

AesDerivedKeyParams

Schnittstelle

Wörterbuch-Objekt, das als <code>derivedKeyType</code> an <code>SubtleCrypto.deriveKey()</code> übergeben wird, um einen AES-Schlüssel (AES-CTR, AES-CBC, AES-GCM, AES-KW) abzuleiten.

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

Signatur

interface AesDerivedKeyParams { name: string; length: number }

Beschreibung

AesDerivedKeyParams ist keine Klasse, sondern ein Wörterbuch (Dictionary) der Web Crypto API – also ein gewöhnliches JavaScript-Objekt mit festgelegten Eigenschaften. Es beschreibt, welche Art von AES-Schlüssel SubtleCrypto.deriveKey() erzeugen soll: den Algorithmus (name) und die Schlüssellänge in Bit (length).

Gebraucht wird es immer dann, wenn aus einem Ausgangsmaterial ein symmetrischer AES-Schlüssel entstehen soll, zum Beispiel:

  • aus einem Passwort per PBKDF2 (passwortbasierte Verschlüsselung),
  • aus einem gemeinsamen Geheimnis nach einem ECDH- bzw. X25519-Schlüsselaustausch,
  • aus einem Hauptschlüssel per HKDF (Ableitung mehrerer Teilschlüssel).

Der abgeleitete Schlüssel ist ein CryptoKey, der direkt mit encrypt()/decrypt() bzw. wrapKey()/unwrapKey() verwendet werden kann – vorausgesetzt, die passenden keyUsages wurden angegeben.

Wichtig: Das Wörterbuch legt nur den Zielschlüssel fest. Die Parameter des Ableitungsverfahrens selbst (Salz, Iterationen, Hash, öffentlicher Schlüssel) gehören in das erste Argument von deriveKey() (Pbkdf2Params, HkdfParams oder EcdhKeyDeriveParams).

Parameter

Name Typ Default Beschreibung
$name Pflicht string Name des AES-Algorithmus: "AES-CTR", "AES-CBC", "AES-GCM" oder "AES-KW". Groß-/Kleinschreibung wird normalisiert.
$length Pflicht number Schlüssellänge in Bit: 128, 192 oder 256. Andere Werte führen zu einem OperationError.

Rückgabewert

Typ
Object (Dictionary)
Beschreibung
Kein Rückgabewert im eigentlichen Sinn – das Objekt wird als derivedKeyType an deriveKey() übergeben, das ein Promise<CryptoKey> liefert.

Beispiele

AES-GCM-Schlüssel aus einem Passwort ableiten (PBKDF2)

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

  // AesDerivedKeyParams: Zielschlüssel beschreiben
  const aesParams = { name: 'AES-GCM', length: 256 };

  return crypto.subtle.deriveKey(
    { name: 'PBKDF2', salt, iterations: 600_000, hash: 'SHA-256' },
    baseKey,
    aesParams,
    false,
    ['encrypt', 'decrypt']
  );
};

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

Gemeinsamen AES-Schlüssel per ECDH vereinbaren

const genPair = () => crypto.subtle.generateKey(
  { name: 'ECDH', namedCurve: 'P-256' }, false, ['deriveKey']
);

const alice = await genPair();
const bob = await genPair();

const aesParams = { name: 'AES-GCM', length: 128 };

const aliceKey = await crypto.subtle.deriveKey(
  { name: 'ECDH', public: bob.publicKey },
  alice.privateKey, aesParams, true, ['encrypt', 'decrypt']
);
const bobKey = await crypto.subtle.deriveKey(
  { name: 'ECDH', public: alice.publicKey },
  bob.privateKey, aesParams, true, ['encrypt', 'decrypt']
);

const toHex = async (k) => [...new Uint8Array(await crypto.subtle.exportKey('raw', k))]
  .map((b) => b.toString(16).padStart(2, '0')).join('');

console.log((await toHex(aliceKey)) === (await toHex(bobKey)));
true

Abgeleiteten Schlüssel zum Verschlüsseln nutzen (HKDF + AES-GCM)

const master = await crypto.subtle.importKey(
  'raw', crypto.getRandomValues(new Uint8Array(32)), 'HKDF', false, ['deriveKey']
);

const key = await crypto.subtle.deriveKey(
  {
    name: 'HKDF', hash: 'SHA-256',
    salt: new Uint8Array(16),
    info: new TextEncoder().encode('nachrichten-v1')
  },
  master,
  { name: 'AES-GCM', length: 256 }, // AesDerivedKeyParams
  false,
  ['encrypt', 'decrypt']
);

const iv = crypto.getRandomValues(new Uint8Array(12));
const cipher = await crypto.subtle.encrypt(
  { name: 'AES-GCM', iv }, key, new TextEncoder().encode('Hallo Welt')
);
const plain = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, cipher);
console.log(new TextDecoder().decode(plain));
Hallo Welt

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: crypto.subtle gibt es nur über HTTPS (oder localhost). Über HTTP ist es undefined.
  • Schlüssellänge 192 Bit: Chromium-basierte Browser unterstützen AES-192 nicht und werfen einen OperationError. Für maximale Kompatibilität besser 128 oder 256 verwenden.
  • Usages müssen zum Algorithmus passen: AES-KW erlaubt nur wrapKey/unwrapKey, die anderen AES-Varianten encrypt, decrypt, wrapKey, unwrapKey. Unpassende Angaben führen zu einem SyntaxError.
  • Das Basis-Schlüsselobjekt muss die Usage deriveKey haben, sonst gibt es einen InvalidAccessError.
  • Sicherheit: Bei PBKDF2 ein zufälliges, pro Nutzer eindeutiges Salz und eine hohe Iterationszahl (OWASP empfiehlt ≥ 600.000 bei SHA-256) verwenden. Bei ECDH das gemeinsame Geheimnis idealerweise über HKDF weiterverarbeiten, statt es direkt als AES-Schlüssel zu nutzen. Bei AES-GCM den IV niemals mit demselben Schlüssel wiederverwenden.
  • AesDerivedKeyParams existiert zur Laufzeit nicht als globales Objekt – man übergibt einfach ein Objektliteral. Den Namen gibt es nur in der Spezifikation und in TypeScript-Typdefinitionen.
  • In Node.js steht die API als globalThis.crypto.subtle (ab v19) bzw. require('node:crypto').webcrypto.subtle (ab v15) zur Verfügung.