„Ich kodiere es in Base64, damit niemand es lesen kann.“ Dieser Satz taucht in Code-Reviews, Slack-Nachrichten und Stack-Overflow-Antworten öfter auf, als er sollte. Base64 ist keine Verschlüsselung. Es ist keine Obfuskation. Es ist keine Sicherheit irgendeiner Art. Es zu dekodieren erfordert einen Funktionsaufruf und null Wissen über irgendeinen Schlüssel oder ein Geheimnis. Dieser Artikel erklärt, was Base64 wirklich ist, warum die Verwechslung sich hält und was man stattdessen verwendet, wenn man Daten tatsächlich schützen muss.
Was Base64 wirklich ist
Base64 ist ein Kodierungsschema —— eine umkehrbare Zuordnung zwischen Binärdaten und einer Menge von 64 druckbaren ASCII-Zeichen (A–Z, a–z, 0–9, +, /, mit = als Padding).
Aus je 3 Eingabebytes werden 4 Base64-Zeichen. Der Algorithmus ist vollständig deterministisch und benötigt keinen Schlüssel:
// Kodieren
btoa("hello") // → "aGVsbG8="
btoa("secret password") // → "c2VjcmV0IHBhc3N3b3Jk"
// Dekodieren —— ein Aufruf, kein Schlüssel
atob("c2VjcmV0IHBhc3N3b3Jk") // → "secret password"Das ist alles. Jeder mit Zugriff auf die kodierte Zeichenkette kann sie sofort dekodieren, in jeder Sprache, in jeder Umgebung, ohne zusätzliche Informationen.
Warum die Verwechslung existiert
Base64-kodierte Zeichenketten sehen aus wie verschlüsselte Daten. Sie sind voll mit gemischten Groß- und Kleinbuchstaben, Zahlen und Sonderzeichen und haben keine sichtbare Ähnlichkeit mit der ursprünglichen Eingabe. Dieses visuelle Rauschen reicht, um einen nicht-technischen Beobachter zu täuschen —— und überraschend oft auch einen technischen.
Das Muster wird auch durch Nähe verstärkt. Base64 erscheint ständig in Sicherheitskontexten:
- HTTPS-Zertifikate sind Base64-kodiert (PEM-Format)
- JWT-Token verwenden Base64url-Kodierung für Header und Payload
- HTTP-Basic-Authentifizierung sendet Anmeldedaten als Base64
- SSH-Schlüssel werden als Base64 gespeichert
- Verschlüsselte Daten werden für den Transport oft in Base64 kodiert
Base64 an all diesen sicherheitsnahen Stellen zu sehen, führt Entwickler dazu, Kodierung mit Sicherheit zu verwechseln. Die Kodierung ist nur die Verpackung; die Sicherheit kommt von den kryptographischen Operationen darunter.
Kodierung vs Verschlüsselung: der zentrale Unterschied
Die Unterscheidung ist einfach und absolut:
| Kodierung (Base64) | Verschlüsselung (AES, RSA …) | |
|---|---|---|
| Zweck | Binärdaten als Text darstellen | Daten vor unbefugten Parteien verbergen |
| Schlüssel nötig? | Nein | Ja |
| Von jedem umkehrbar? | Ja —— ein Funktionsaufruf | Nur mit dem richtigen Schlüssel |
| Fügt Vertraulichkeit hinzu? | Nein | Ja (bei korrekter Verwendung) |
| Ausgabegröße | ~33 % größer als Eingabe | Variiert je nach Algorithmus |
Verschlüsselung transformiert Daten mit einem Schlüssel so, dass das Wiederherstellen des Originals ohne den Schlüssel rechnerisch nicht durchführbar ist. Base64-Kodierung hat diese Eigenschaft nicht.
Sicherheitsfehler aus der Praxis
„Kodierte“ Geheimnisse im Quellcode ablegen
// ❌ Das ist nicht geheim —— jeder kann es dekodieren
const API_KEY = atob("c2stbGl2ZS1hYmMxMjM0NTY3ODk=");
// Jeder, der diesen Code liest, führt aus:
atob("c2stbGl2ZS1hYmMxMjM0NTY3ODk=") // → "sk-live-abc123456789"Automatische Secret-Scanning-Tools (GitHub Secret Scanning, GitGuardian, truffleHog) dekodieren Base64-Zeichenketten als Teil ihrer Erkennung. Wenn Sie erwarten, dass Base64 sie aufhält, wird das nicht funktionieren.
HTTP-Basic-Authentifizierung
// Der Authorization-Header sieht so aus:
Authorization: Basic dXNlcjpwYXNzd29yZA==
// Dieses Base64 lässt sich trivial dekodieren:
atob("dXNlcjpwYXNzd29yZA==") // → "user:password"HTTP-Basic-Authentifizierung ist nur über HTTPS sicher —— die TLS-Schicht liefert die eigentliche Verschlüsselung. Das Base64 im Header dient rein dazu, das Paar username:password als einen einzigen Textwert zu kodieren, nicht es zu verbergen. Über reines HTTP kann jeder, der den Verkehr abfängt, die Anmeldedaten sofort lesen.
JWT-„Token“ als Geheimnisse behandeln
// Ein JWT sieht aus wie drei Base64url-Abschnitte, durch Punkte verbunden:
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjQyfQ.abc123
// Der mittlere Abschnitt (Payload) dekodiert zu:
atob("eyJ1c2VySWQiOjQyfQ") // → '{"userId":42}'JWT-Payloads sind nicht verschlüsselt —— sie sind Base64url-kodiert und signiert. Jeder, der den Token erhält, kann die Payload lesen. Die Signatur verhindert Manipulation, aber bietet keine Vertraulichkeit. Stecken Sie nie sensible Daten (Passwörter, Kartennummern, personenbezogene Informationen) in eine JWT-Payload, es sei denn, Sie verwenden JWE (JSON Web Encryption), das ein anderer und viel weniger gebräuchlicher Standard ist.
Daten in URLs obfuskieren
// Häufiges Muster in Legacy-Apps
/profile?data=eyJ1c2VySWQiOjQyfQ==
// Fügen Sie das in einen beliebigen Decoder ein:
atob("eyJ1c2VySWQiOjQyfQ==") // → '{"userId":42}' Base64 in URLs fügt keine Sicherheit hinzu. Es bricht auch leicht —— die Zeichen + und / des Standard-Base64 sind nicht URL-sicher und müssen prozent-kodiert werden, weshalb Base64url (+ → -, / → _, ohne Padding) als separate Variante existiert.
Wofür Base64 wirklich da ist
Base64 hat legitime und wichtige Einsatzzwecke —— nur eben nicht für Sicherheit:
- Binärdaten in Textformate einbetten —— Bilder, Schriften und Dateien als
data:-URIs in HTML/CSS eingebettet oder als Anhänge in JSON-API-Antworten - E-Mail-Anhänge —— MIME-Kodierung verwendet Base64, um Binärdateien über Protokolle zu übertragen, die nur 7-Bit-ASCII verarbeiten
- Transportsicherheit —— manche Kanäle beschädigen Binärdaten (Nullbytes, Steuerzeichen); Base64 garantiert, dass der Inhalt unversehrt ankommt
- Opake Bezeichner —— eine ID oder einen Cursor als Base64 zu kodieren, signalisiert API-Konsumenten „versuche das nicht zu parsen“, bietet aber keine Sicherheit
Was verwenden, wenn Sie wirklich Sicherheit brauchen
Wenn Ihr Ziel ist, unbefugten Zugriff auf Daten zu verhindern, verwenden Sie ein echtes kryptographisches Werkzeug:
| Ziel | Was verwenden |
|---|---|
| Daten at-rest verschlüsseln | AES-256-GCM (symmetrische Verschlüsselung) |
| Daten in transit verschlüsseln | TLS 1.3 (HTTPS) |
| Passwörter hashen | bcrypt, scrypt oder Argon2 —— niemals SHA-256 allein |
| Token signieren | HMAC-SHA256 (wie JWT HS256) oder RS256 |
| Geheimnisse speichern | Umgebungsvariablen, ein Secret-Manager (Vault, AWS Secrets Manager) |
| Token Ende-zu-Ende verschlüsseln | JWE (JSON Web Encryption) —— nicht einfaches JWT |
Wenn Sie wirklich einen verschlüsselten Token brauchen: JWE und JOSE
Ein Standard-JWT ist signiert (JWS), nicht verschlüsselt —— die Payload ist lesbar. Wenn Sie wirklich Vertraulichkeit für Claims brauchen, verwenden Sie ein JWE (JSON Web Encryption, RFC 7516). JWE ist Teil der JOSE-Standardfamilie:
- JOSE-Algorithmen —— Inhaltsverschlüsselung (z. B.
A256GCM) und Schlüsselmanagement (z. B.RSA-OAEP-256,ECDH-ES,A256KW). „alg“ wählt, wie der Content-Encryption-Key verpackt wird; „enc“ wählt, wie die Payload selbst verschlüsselt wird. - Schlüssel-Wrapping —— JWE generiert pro Nachricht einen frischen Content-Encryption-Key und verpackt ihn unter dem Schlüssel des Empfängers (asymmetrisch oder symmetrisch). Der verpackte Schlüssel reist im Token-Header. So kann derselbe Klartext für verschiedene Empfänger verschlüsselt werden, ohne den Body neu zu verschlüsseln.
- JWE-Kompaktform —— fünf Base64url-Abschnitte durch Punkte verbunden (header.key.iv.ciphertext.tag), optisch wie ein JWT, aber mit vier statt drei Teilen.
Wählen Sie eine geprüfte Bibliothek (jose, node-jose, python-jose), statt JWE selbst zu implementieren —— die Kombinationen aus Algorithmen und Schlüsselformaten sind subtil, und das stille Zur ückfallen auf schwache Algorithmen ist ein klassischer JOSE-Bug.
Ein schneller Test für Ihren eigenen Code
Suchen Sie Ihre Codebasis nach btoa(, atob( und Buffer.from(…, 'base64') durch. Fragen Sie sich zu jedem Vorkommen:
- Mache ich das, damit der Text in ein Feld passt oder den Transport übersteht? → Gut.
- Mache ich das, um Daten zu verbergen vor jemandem? → Ersetzen Sie es durch echte Verschlüsselung oder Zugriffskontrolle.
Häufig gestellte Fragen
Ist Base64 Verschlüsselung?
Nein. Base64 ist eine schlüssellos umkehrbare Kodierung —— jeder kann sie in einem Aufruf dekodieren (atob()). Verschlüsselung erfordert einen Schlüssel und macht es undurchführbar, den Inhalt ohne ihn wiederherzustellen.
Ist es sicher, Passwörter oder API-Keys in Base64 zu speichern?
Nein. Die Dekodierung ist trivial, und Secret-Scanner dekodieren Base64 automatisch. Verwenden Sie einen Secret-Manager oder Umgebungsvariablen und hashen Sie Passwörter mit bcrypt, scrypt oder Argon2.
Kann jeder die Payload eines JWT lesen?
Ja. JWT-Payloads sind Base64url-kodiert und signiert, nicht verschlüsselt —— jeder mit dem Token kann alle Claims lesen. Stecken Sie nie Geheimnisse in ein JWT, es sei denn, Sie verwenden JWE. Token in Online-Tools zu kleben ist riskant; siehe warum Sie sensibles JSON nicht online einfügen sollten.
Wofür ist Base64 dann?
Binärdaten sicher als Text darstellen —— data:-URIs, E-Mail-Anhänge (MIME) und Transport über Kanäle, die nur ASCII verarbeiten. Es ist eine Verpackung, keine Sicherheitsmaßnahme.
Im Browser kodieren und dekodieren
Müssen Sie jetzt eine Base64-Zeichenkette inspizieren? Base64-Kodierung und -Dekodierung auf fixjson.org erlaubt Ihnen, jede Zeichenkette sofort zu kodieren oder zu dekodieren —— einschließlich vollständigem Unicode und UTF-8 —— ohne etwas zu installieren. Nützlich zum Debuggen von JWT-Payloads, Inspizieren von API-Antworten oder zu sehen, was sich in einer data:-URI versteckt.
- Base64 kodieren und dekodieren —— sofort, im Browser, keine Daten an einen Server gesendet
- RFC 4648: Der Base64-Standard —— die Geschichte und formale Definition von Base64 und Base64url
- Wie man ein JWT dekodiert —— die Claims eines Tokens lesen und warum Dekodieren nicht Verifizieren ist
- RFC 7519: JSON Web Token (JWT) —— wie Base64url im JWT-Standard verwendet wird, und Sicherheitserwägungen
- URL dekodieren —— eine URL oder einen Query-String prozent-dekodieren
- JSON Stringify —— einen JSON-Wert als escapetes String-Literal kodieren