Start · Sprachen · JavaScript · Referenz · AesGcmParams

AesGcmParams

Schnittstelle

Parameter-Wörterbuch für AES-GCM in <code>SubtleCrypto.encrypt()</code>, <code>decrypt()</code>, <code>wrapKey()</code> und <code>unwrapKey()</code>: legt IV, Zusatzdaten und Tag-Länge fest.

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

Signatur

interface AesGcmParams extends Algorithm { name: "AES-GCM"; iv: BufferSource; additionalData?: BufferSource; tagLength?: number }

Beschreibung

AesGcmParams ist keine Klasse, sondern ein Wörterbuch (Dictionary) der Web Crypto API, also ein normales Objekt-Literal. Du übergibst es als algorithm-Argument an crypto.subtle.encrypt(), decrypt(), wrapKey() oder unwrapKey(), wenn du den Modus AES-GCM (Galois/Counter Mode) nutzt.

AES-GCM ist ein Verfahren für authentifizierte Verschlüsselung (AEAD). Die Daten werden verschlüsselt und bekommen zusätzlich einen Authentifizierungs-Tag. Wird der Geheimtext verändert, schlägt decrypt() mit einem OperationError fehl. Deshalb ist AES-GCM in der Web Crypto API meist die empfohlene Wahl für symmetrische Verschlüsselung.

Das Wichtigste ist der Initialisierungsvektor (iv). Er muss für jede Verschlüsselung mit demselben Schlüssel eindeutig sein. Geheim muss er nicht sein. Du speicherst oder überträgst ihn üblicherweise zusammen mit dem Geheimtext. Mit additionalData lassen sich unverschlüsselte Metadaten (z. B. Header oder Benutzer-IDs) an den Geheimtext binden. Sie werden mit authentifiziert, aber nicht verschlüsselt.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Muss "AES-GCM" sein.
$iv Pflicht ArrayBuffer|TypedArray|DataView (BufferSource) Initialisierungsvektor. Empfohlen sind 12 Byte (96 Bit), z. B. aus crypto.getRandomValues(new Uint8Array(12)). Er darf mit demselben Schlüssel niemals wiederverwendet werden. Beim Entschlüsseln brauchst du exakt denselben IV.
$additionalData ArrayBuffer|TypedArray|DataView (BufferSource) leer Optionale Zusatzdaten (AAD). Sie werden authentifiziert, aber nicht verschlüsselt. Beim Entschlüsseln müssen sie byte-genau gleich übergeben werden, sonst schlägt die Prüfung fehl.
$tagLength number 128 Länge des Authentifizierungs-Tags in Bit. Erlaubt sind 32, 64, 96, 104, 112, 120 und 128. Empfohlen ist 128. Beim Ver- und Entschlüsseln muss derselbe Wert gelten.

Rückgabewert

Typ
AesGcmParams (Objekt)
Beschreibung
Es gibt keinen Rückgabewert, denn es ist ein Parameterobjekt. encrypt() liefert mit diesem Objekt ein Promise<ArrayBuffer>: den Geheimtext, an dessen Ende der Tag angehängt ist.

Beispiele

Text verschlüsseln und wieder entschlüsseln

const key = await crypto.subtle.generateKey(
  { name: 'AES-GCM', length: 256 },
  true,
  ['encrypt', 'decrypt']
);

const iv = crypto.getRandomValues(new Uint8Array(12)); // pro Nachricht neu!
const plaintext = new TextEncoder().encode('Geheime Nachricht');

/** @type {AesGcmParams} */
const params = { name: 'AES-GCM', iv };

const ciphertext = await crypto.subtle.encrypt(params, key, plaintext);
console.log('Länge Geheimtext:', ciphertext.byteLength); // 17 + 16 Byte Tag

const decrypted = await crypto.subtle.decrypt(params, key, ciphertext);
console.log(new TextDecoder().decode(decrypted));
Länge Geheimtext: 33 Geheime Nachricht

Metadaten mit additionalData binden

const key = await crypto.subtle.generateKey(
  { name: 'AES-GCM', length: 128 }, false, ['encrypt', 'decrypt']
);
const enc = new TextEncoder();
const iv = crypto.getRandomValues(new Uint8Array(12));
const aad = enc.encode('user-id=42');

const ct = await crypto.subtle.encrypt(
  { name: 'AES-GCM', iv, additionalData: aad, tagLength: 128 },
  key,
  enc.encode('Kontostand: 1000 €')
);

try {
  // Falsche Zusatzdaten: Die Authentifizierung schlägt fehl
  await crypto.subtle.decrypt(
    { name: 'AES-GCM', iv, additionalData: enc.encode('user-id=43') },
    key,
    ct
  );
} catch (err) {
  console.log(err.name);
}
OperationError

IV zusammen mit dem Geheimtext speichern (Base64)

const toB64 = (buf) => btoa(String.fromCharCode(...new Uint8Array(buf)));
const fromB64 = (s) => Uint8Array.from(atob(s), (c) => c.charCodeAt(0));

const encryptString = async (key, text) => {
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const ct = await crypto.subtle.encrypt(
    { name: 'AES-GCM', iv }, key, new TextEncoder().encode(text)
  );
  const out = new Uint8Array(iv.length + ct.byteLength);
  out.set(iv);
  out.set(new Uint8Array(ct), iv.length);
  return toB64(out);
};

const decryptString = async (key, b64) => {
  const data = fromB64(b64);
  const iv = data.slice(0, 12);
  const pt = await crypto.subtle.decrypt(
    { name: 'AES-GCM', iv }, key, data.slice(12)
  );
  return new TextDecoder().decode(pt);
};

const key = await crypto.subtle.generateKey(
  { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']
);
const token = await encryptString(key, 'Hallo Welt');
console.log(await decryptString(key, token));
Hallo Welt

// Wichtig · Fallstricke

  • IV niemals wiederverwenden: Wenn derselbe Schlüssel zweimal mit demselben IV verwendet wird, bricht die Sicherheit von GCM komplett zusammen. Angreifer können dann Klartexte per XOR vergleichen und Tags fälschen. Nimm pro Nachricht einen neuen Zufalls-IV mit 12 Byte oder einen streng monoton steigenden Zähler. Bei Zufalls-IVs solltest du den Schlüssel nach etwa 232 Nachrichten wechseln.
  • Tag im Geheimtext: Die Web Crypto API hängt den Tag an das Ende des ArrayBuffer an. Andere Bibliotheken wie Node.js crypto.createCipheriv geben den Tag dagegen getrennt aus. Das musst du bei der Zusammenarbeit beachten.
  • Kurze Tags (unter 96 Bit) schwächen die Integritätsprüfung deutlich. Verwende sie nur, wenn du genau weißt, warum.
  • Ein Fehler beim Entschlüsseln (falscher Schlüssel, IV, AAD, Tag oder manipulierte Daten) führt immer zu einem allgemeinen OperationError. Genauere Angaben gibt es absichtlich nicht.
  • crypto.subtle steht nur in sicheren Kontexten (HTTPS, localhost) zur Verfügung. Von den modernen Browsern unterstützen es alle. In Node.js ist es über globalThis.crypto.subtle erreichbar (global ab Version 19).
  • Die maximale Klartextlänge liegt bei etwa 239−256 Bit pro Aufruf. Sehr große Dateien solltest du in Blöcke aufteilen, jeweils mit eigenem IV.