Start · Sprachen · JavaScript · Referenz · SubtleCrypto.decrypt()

SubtleCrypto.decrypt()

Methode

Entschlüsselt Daten mit einem <code>CryptoKey</code> und einem Algorithmus (AES-GCM, AES-CBC, AES-CTR, RSA-OAEP) und liefert ein <code>Promise&lt;ArrayBuffer&gt;</code> mit dem Klartext.

seit JavaScript Baseline: alle modernen Browser (sicherer Kontext Kategorie: webapi

Signatur

SubtleCrypto.prototype.decrypt(algorithm, key, data)

Beschreibung

Die Methode decrypt() der Schnittstelle SubtleCrypto ist das Gegenstück zu encrypt(). Sie nimmt verschlüsselte Binärdaten, einen passenden Schlüssel und dieselben Algorithmus-Parameter, die beim Verschlüsseln verwendet wurden, und gibt ein Promise zurück, das mit dem entschlüsselten Klartext als ArrayBuffer erfüllt wird.

Unterstützt werden diese Algorithmen:

  • RSA-OAEP: asymmetrisch, entschlüsselt wird mit dem privaten Schlüssel ({ name: "RSA-OAEP", label? }).
  • AES-GCM: authentifizierte Verschlüsselung, braucht dieselbe iv und optional dieselben additionalData und dieselbe tagLength. Das wird in den meisten Fällen empfohlen.
  • AES-CBC: braucht dieselbe 16-Byte-iv.
  • AES-CTR: braucht denselben counter und dieselbe length.

Der Schlüssel muss mit der Verwendung "decrypt" in keyUsages erzeugt oder importiert worden sein, und sein Algorithmus muss zu algorithm.name passen. Das Ergebnis ist immer ein ArrayBuffer. Text gewinnst du daraus typischerweise mit TextDecoder zurück.

Parameter

Name Typ Default Beschreibung
$algorithm Pflicht RsaOaepParams | AesGcmParams | AesCbcParams | AesCtrParams Objekt mit name und den algorithmusspezifischen Parametern, z. B. { name: "AES-GCM", iv }. Die Werte müssen identisch mit denen beim Verschlüsseln sein.
$key Pflicht CryptoKey Schlüssel zum Entschlüsseln. Bei RSA-OAEP der private Schlüssel, bei AES der geheime Schlüssel. Er muss "decrypt" in usages enthalten.
$data Pflicht ArrayBuffer | TypedArray | DataView Die verschlüsselten Daten (Chiffretext). Bei AES-GCM hängt das Authentifizierungs-Tag am Ende.

Rückgabewert

Typ
Promise<ArrayBuffer>
Beschreibung
Promise, das mit dem Klartext als ArrayBuffer erfüllt wird. Es wird mit InvalidAccessError abgelehnt, wenn der Schlüssel nicht passt oder nicht zum Entschlüsseln freigegeben ist, und mit OperationError, wenn die Daten beschädigt sind, das GCM-Tag nicht stimmt oder Parameter wie die IV falsch sind.

Beispiele

Text mit AES-GCM verschlüsseln und wieder entschlüsseln

const { subtle } = globalThis.crypto;

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

// Für jede Verschlüsselung eine neue, zufällige 12-Byte-IV erzeugen
const iv = crypto.getRandomValues(new Uint8Array(12));
const plaintext = new TextEncoder().encode("Geheime Nachricht");

const ciphertext = await subtle.encrypt({ name: "AES-GCM", iv }, key, plaintext);

// Entschlüsseln – mit derselben IV
const decrypted = await subtle.decrypt({ name: "AES-GCM", iv }, key, ciphertext);
console.log(new TextDecoder().decode(decrypted));
Geheime Nachricht

Manipulierte Daten erkennen (AES-GCM)

const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 128 }, false, ["encrypt", "decrypt"]
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const ct = new Uint8Array(
  await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, new TextEncoder().encode("Betrag: 100 €"))
);

ct[0] ^= 0xff; // ein Byte verfälschen

try {
  await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ct);
} catch (err) {
  console.log(err.name); // Integritätsprüfung schlägt fehl
}
OperationError

RSA-OAEP: mit öffentlichem Schlüssel verschlüsseln, mit privatem entschlüsseln

const { publicKey, privateKey } = await crypto.subtle.generateKey(
  {
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256"
  },
  false,
  ["encrypt", "decrypt"]
);

const data = new TextEncoder().encode("Sitzungs-Token 42");
const encrypted = await crypto.subtle.encrypt({ name: "RSA-OAEP" }, publicKey, data);
const decrypted = await crypto.subtle.decrypt({ name: "RSA-OAEP" }, privateKey, encrypted);

console.log(new TextDecoder().decode(decrypted));
Sitzungs-Token 42

Gespeicherte Base64-Daten (IV + Chiffretext) entschlüsseln

const fromBase64 = (b64) => Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));

// Format: die ersten 12 Byte sind die IV, danach folgt der Chiffretext mit Tag
async function decryptPayload(b64, key) {
  const bytes = fromBase64(b64);
  const iv = bytes.slice(0, 12);
  const ciphertext = bytes.slice(12);
  const buf = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ciphertext);
  return JSON.parse(new TextDecoder().decode(buf));
}

// Verwendung: const obj = await decryptPayload(localStorage.getItem("daten"), key);

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: crypto.subtle gibt es nur über HTTPS oder localhost. Auf unsicheren Seiten ist es undefined. In Node.js steht es ab Version 15 als globalThis.crypto.subtle bzw. über require(\"node:crypto\").webcrypto zur Verfügung.
  • Parameter müssen exakt übereinstimmen: IV, Counter, additionalData, tagLength und bei RSA-OAEP label und Hash müssen dieselben sein wie beim Verschlüsseln. Sonst folgt ein OperationError ohne weitere Details.
  • Die IV ist nicht geheim, muss aber gespeichert werden: Üblich ist, sie dem Chiffretext voranzustellen. Eine IV darf bei AES-GCM mit demselben Schlüssel nie wiederverwendet werden.
  • AES-CBC und AES-CTR prüfen die Integrität nicht: Manipulierte Daten können unbemerkt zu falschem Klartext werden. Setze AES-GCM ein oder ergänze einen HMAC.
  • Fehlermeldungen verraten absichtlich wenig. Gib sie nicht ungefiltert an Nutzer weiter, damit keine Padding-Oracle-Angriffe möglich werden (relevant bei CBC).
  • RSA-OAEP taugt nur für kleine Datenmengen. Die Grenze liegt bei etwa Schlüssellänge minus Hash-Overhead, bei 2048 Bit mit SHA-256 also rund 190 Byte. Für größere Daten nimmst du hybride Verschlüsselung: AES-Schlüssel mit RSA verpacken (wrapKey/unwrapKey).
  • Rückgabewert ist ein ArrayBuffer, kein String. Du brauchst TextDecoder für die Umwandlung.