Fehlermeldung
Malformed UTF-8 data
CryptoJS — thrown by .toString(CryptoJS.enc.Utf8) after decrypt
Was der Fehler bedeutet
CryptoJS hat dein Chiffrat in Bytes entschlüsselt, die kein gültiges UTF-8 sind, und die Umwandlung in einen String ist fehlgeschlagen. Da AES in CryptoJS (CBC-Modus) keine Integritätsprüfung hat, lässt ein falscher Schlüssel die Entschlüsselung nicht scheitern – er erzeugt nur zufällige Bytes, und der UTF-8-Decoder bemerkt das als Erster. Derselbe falsche Schlüssel kann statt dieses Fehlers auch einen leeren String liefern (wenn die Padding-Prüfung zufällig sauber fehlschlägt); beide Symptome haben also dieselbe Diagnose.
Warum der Fehler auftritt
Falscher Schlüssel oder falsche Passphrase
häufigWer mit einem anderen Schlüssel entschlüsselt als dem, mit dem verschlüsselt wurde, erhält eine pseudozufällige Ausgabe. Welches Symptom du bekommst, hängt von der Länge der Nachricht ab: In unserem Test warf bei einer 29-Byte-Nachricht etwa jede achte Entschlüsselung mit falschem Schlüssel diesen Fehler, bei einer 100-Byte-Nachricht etwa die Hälfte und bei 300 Byte jede; fast alle übrigen lieferten "" – so oder so steht der Schlüssel unter Verdacht.
Unterschiedliche Schlüsselableitung auf beiden Seiten
häufigCryptoJS.AES.encrypt(msg, "passphrase") leitet Schlüssel und IV über eine OpenSSL-kompatible KDF mit zufälligem Salt ab. Behandelt die Gegenseite die Passphrase als rohen Schlüssel (oder entschlüsselt eine andere Plattform ohne diese KDF), unterscheiden sich die abgeleiteten Schlüssel, und die Ausgabe ist Datenmüll.
Chiffrat bei der Übertragung beschädigt
gelegentlichDurch URL-Kodierung verstümmeltes Base64 (+ wird zum Leerzeichen), Abschneiden beim Speichern oder doppelte Kodierung verändert die Bytes des Chiffrats; die CBC-Entschlüsselung veränderter Bytes liefert Datenmüll, ohne dass auf der Kryptoschicht ein Fehler auftritt.
So behebst du den Fehler
- 1.
Schlüssel explizit und auf beiden Seiten gleich behandeln
Umgehe die Mehrdeutigkeit der Passphrasen-KDF: Übergib einen echten Schlüssel als WordArray und dazu einen expliziten IV, auf beiden Seiten identisch.
js const key = CryptoJS.enc.Hex.parse(hexKey); // 32-byte key, both sides const iv = CryptoJS.enc.Hex.parse(hexIv); // 16-byte IV, both sides const ct = CryptoJS.AES.encrypt(plaintext, key, { iv }); const pt = CryptoJS.AES.decrypt(ct.toString(), key, { iv }) .toString(CryptoJS.enc.Utf8); - 2.
Leere Ausgabe als denselben Fehler behandeln
Prüfe das Ergebnis und melde einen echten Fehler – stille leere Strings verbergen Bugs mit falschen Schlüsseln monatelang.
js const pt = CryptoJS.AES.decrypt(ct, key, { iv }).toString(CryptoJS.enc.Utf8); if (!pt) throw new Error("decryption failed: wrong key/IV or corrupted ciphertext"); - 3.
Authentifiziertes Verfahren bevorzugen
AES-GCM in WebCrypto authentifiziert das Chiffrat: Ein falscher Schlüssel scheitert sichtbar und deterministisch, statt Datenmüll zu erzeugen – damit verschwindet diese Fehlerklasse vollständig.
js const pt = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ct); // wrong key → OperationError, never silent garbage