Zum Inhalt springen
ecdsa.com
WebCrypto crypto.subtleWebCrypto

Fehlermeldung

OperationError: The operation failed for an operation-specific reason

WebCrypto crypto.subtle — browsers & Node

Was der Fehler bedeutet

Der absichtlich vage Sammelfehler von WebCrypto: Das Primitiv selbst ist gescheitert. Bei decrypt() mit AES-GCM heißt das, dass die Prüfung des Authentifizierungs-Tags fehlgeschlagen ist – falscher Schlüssel, falscher IV, falsche zusätzliche Daten oder ein verändertes Chiffrat. Die Spezifikation hält die Meldung generisch, damit Implementierungen nicht verraten, warum eine kryptografische Prüfung gescheitert ist. Bei sign() und deriveBits() deckt derselbe Name interne Fehler des Primitivs ab; die Operation in deinem Stacktrace sagt deshalb mehr als der Meldungstext.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    IV und Chiffrat gemeinsam übertragen, auf beiden Seiten gleich dekodieren

    Stelle den IV dem Chiffrat voran und trenne beides beim Entschlüsseln wieder, damit beide Seiten immer übereinstimmen; verwende überall dieselbe base64-Variante.

    js
    // encrypt
    const iv = crypto.getRandomValues(new Uint8Array(12));
    const ct = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, data);
    const packed = new Uint8Array([...iv, ...new Uint8Array(ct)]);
    
    // decrypt
    const buf = packedFromWire;
    const pt = await crypto.subtle.decrypt(
      { name: "AES-GCM", iv: buf.slice(0, 12) }, key, buf.slice(12),
    );
  2. 2.

    Als Integritätsbefund behandeln, nicht als Datenbeschädigung

    Wirft decrypt einen OperationError, ist die richtige Antwort: „Dieses Chiffrat ist unter diesem Schlüssel nicht authentisch“ – lehne es ab. Versuche es nicht erneut mit verändertem Padding und weiche nicht auf nicht authentifizierte Modi aus; dass die Prüfung fehlschlägt, ist genau die Sicherheitsfunktion.

  3. 3.

    Schlüssel auf beiden Seiten per Fingerabdruck vergleichen

    Exportiere beide Schlüssel und bilde ihre Hashwerte; weichen die Digests voneinander ab, ist das Rätsel in einem Schritt gelöst.

    js
    const raw = await crypto.subtle.exportKey("raw", key);
    const fp = await crypto.subtle.digest("SHA-256", raw);
    console.log(Buffer.from(fp).toString("hex").slice(0, 16)); // compare on both sides

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen