Base64 vs. Base64url 2026: Der kleine Unterschied mit großer Wirkung

Base64 kennt jeder, der schon einmal ein Bild in eine Data-URL gepackt oder in ein JWT geschaut hat. Weniger bekannt ist, dass es zwei Varianten gibt: das Standard-Alphabet mit + und / und die URL-sichere Variante Base64url mit - und _. Wer beide verwechselt, produziert kaputte Links, abgeschnittene Dateinamen und Tokens, die der Server ablehnt. Dieser Artikel erklärt, wie Base64 funktioniert, warum das Standard-Alphabet in URLs stört und wann du zwingend Base64url nach RFC 4648 brauchst.

Was Base64 überhaupt macht

Base64 ist ein Encoding, kein Verschlüsselungsverfahren. Seine einzige Aufgabe: beliebige Bytes so umschreiben, dass sie sich als reiner ASCII-Text transportieren lassen. Das ist überall dort nötig, wo ein Kanal nur »druckbare« Zeichen verträgt: E-Mail-Header, JSON-Felder, XML, URLs oder eine Data-URL im HTML.

Das Prinzip ist simpel. Base64 nimmt den Byte-Strom und zerlegt ihn in Blöcke zu je 3 Bytes. Drei Bytes sind 24 Bit. Diese 24 Bit liest Base64 nicht in 8er-Gruppen, sondern in vier 6-Bit-Gruppen. Jede 6-Bit-Gruppe kann einen Wert von 0 bis 63 annehmen – und genau 64 Zeichen umfasst das Alphabet, das jedem dieser Werte ein druckbares Zeichen zuordnet. Aus 3 Bytes werden also 4 Zeichen.

Daraus folgt der bekannte Overhead: vier Ausgabezeichen für drei Eingabebytes, ein Verhältnis von 4:3, also rund 33 % mehr Datenvolumen. Ein 900 KB großes Bild wird als Base64 rund 1,2 MB groß. Deshalb lohnt sich das Inline-Einbetten per Data-URL nur bei kleinen Assets.

Das Standard-Alphabet: A–Z, a–z, 0–9, + und /

RFC 4648, der maßgebliche Standard aus dem Jahr 2006, definiert in Section 4 das klassische Base64-Alphabet. Die ersten 26 Werte (0–25) sind die Großbuchstaben A–Z, die nächsten 26 (26–51) die Kleinbuchstaben a–z, danach die Ziffern 0–9 für die Werte 52 bis 61. Bleiben zwei Plätze: Wert 62 ist das Pluszeichen +, Wert 63 der Schrägstrich /.

Ein konkretes Beispiel macht es greifbar. Die drei Bytes des Wortes Man (ASCII 77, 97, 110) ergeben in Base64 die Zeichenfolge TWFu. Das ist der Lehrbuchfall ohne Rest. Genauso wird aus dem Klassiker Hello, World! die Zeichenkette SGVsbG8sIFdvcmxkIQ== – mit den beiden Gleichheitszeichen am Ende, zu denen wir gleich kommen.

Wichtig: Diese beiden Sonderzeichen + und / sind der ganze Streitpunkt. Sie sind in reinem Text völlig unproblematisch, aber genau sie machen Ärger, sobald das Ergebnis in eine URL oder einen Dateinamen wandert.

Das Padding mit dem Gleichheitszeichen

Base64 arbeitet in 3-Byte-Blöcken – doch nicht jede Datei ist ein glattes Vielfaches von drei. Bleibt am Ende ein Rest von einem oder zwei Bytes, füllt der Encoder mit Nullbits auf und markiert die Lücke mit dem Padding-Zeichen =. Bleibt 1 Byte übrig, entstehen zwei Ausgabezeichen plus ==; bleiben 2 Bytes, sind es drei Zeichen plus ein einzelnes =.

Das = trägt selbst keine Daten. Es sorgt nur dafür, dass die Ausgabe immer ein Vielfaches von vier Zeichen lang ist – praktisch, wenn mehrere Base64-Blöcke aneinandergehängt werden. Aus M (1 Byte) wird TQ==, aus Ma (2 Bytes) wird TWE=, aus Man (3 Bytes) das schon bekannte TWFu ganz ohne Padding.

Ein Decoder braucht das Padding streng genommen nicht: Aus der Restlänge lässt sich die Anzahl der fehlenden = eindeutig berechnen. Länge modulo 4 gleich 0 heißt kein Padding, gleich 2 heißt zwei = fehlen, gleich 3 heißt eines fehlt. Genau diese Rechnung erlaubt es, das Padding in vielen Kontexten wegzulassen – dazu gleich mehr.

Warum + und / in URLs zum Problem werden

URLs haben ihre eigene Grammatik, festgeschrieben in RFC 3986. In dieser Grammatik sind mehrere Zeichen bereits mit einer festen Bedeutung belegt – und ausgerechnet die beiden Base64-Sonderzeichen gehören dazu. Der Schrägstrich / trennt Pfadsegmente. Steht ein / mitten in einem Base64-String im Pfad einer URL, liest der Server dort eine Verzeichnisgrenze, wo eigentlich Daten stehen sollten.

Noch tückischer ist das Pluszeichen. In der Query-String-Kodierung von Formulardaten (application/x-www-form-urlencoded) steht ein + für ein Leerzeichen. Landet ein Base64-Wert mit + in einem Query-Parameter, macht die Gegenstelle daraus womöglich ein Leerzeichen – der Wert ist zerstört, noch bevor irgendetwas dekodiert wird. Auch das = kollidiert, weil es in Query-Strings Schlüssel und Wert trennt (key=value).

Der klassische Workaround ist Prozent-Kodierung: + wird zu %2B, / zu %2F, = zu %3D. Das funktioniert, bläht den String aber auf und ist fehleranfällig. In Dateinamen hilft es ohnehin nicht, weil / dort auf vielen Systemen schlicht verboten ist. Es braucht eine sauberere Lösung.

Base64url nach RFC 4648 Section 5

Diese Lösung steht in Section 5 desselben RFC 4648 und heißt offiziell »Base 64 Encoding with URL and Filename Safe Alphabet«, kurz Base64url. Die Idee ist minimal-invasiv: Das Verfahren bleibt bitgenau identisch, nur die zwei störenden Zeichen werden getauscht. Wert 62 ist statt + das Minuszeichen -, Wert 63 statt / der Unterstrich _.

Beide Ersatzzeichen sind in URLs und Dateinamen unbedenklich. Das Ergebnis lässt sich ohne Prozent-Kodierung in einen Pfad, einen Query-Parameter oder einen Dateinamen setzen. Aus dem Standard-Base64 a+b/c9== würde in Base64url a-b_c9. Viele Bibliotheken implementieren Base64url schlicht als Standard-Base64 mit anschließendem Austausch von + und /.

Beim Padding geht Base64url meist einen Schritt weiter und lässt das = ganz weg. Möglich ist das, weil sich die Padding-Länge – wie oben gezeigt – aus der Stringlänge rekonstruieren lässt. Manche Kontexte verbieten das Padding sogar ausdrücklich. Ein robuster Decoder sollte beide Fälle akzeptieren: mit und ohne =.

Wo Base64url tatsächlich eingesetzt wird

Der prominenteste Ort ist das JSON Web Token (JWT). Ein JWT besteht aus drei durch Punkte getrennten Teilen: Header, Payload und Signatur. Alle drei sind Base64url ohne Padding kodiert – genau deshalb, weil ein Token oft im Authorization-Header, aber auch in URLs oder Cookies transportiert wird. Ein + oder / mittendrin würde beim Weiterreichen des Tokens zuverlässig etwas kaputt machen.

Wer ein JWT von Hand zerlegt, kennt das Muster: Der mittlere Teil zwischen den Punkten ist die Payload. Kopiert man ihn in einen Standard-Base64-Decoder, scheitert der mitunter am fehlenden Padding oder an einem -, das er nicht kennt. Man muss ihn als Base64url behandeln. Beim JSON Web Key (JWK) gilt dasselbe: Parameter wie Modulus und Exponent eines RSA-Schlüssels werden als Base64url-Strings (Feldtyp base64url) hinterlegt.

Weitere Einsatzorte: WebAuthn kodiert Challenge, Credential-ID und Attestation-Daten als Base64url, weil sie durch JSON und Browser-APIs wandern. Data-URLs nutzen zwar meist Standard-Base64, doch sobald eine solche URL selbst in einen Query-Parameter eingebettet wird, ist Base64url verlässlicher. Und in vielen APIs sind ID-Tokens, Reset-Links oder Bestätigungs-Codes Base64url-kodierte Zufallsbytes.

Base64 ist keine Verschlüsselung

Das größte Missverständnis rund um Base64 – egal ob Standard oder url-Variante – ist der Irrglaube, es biete Schutz. Tut es nicht. Base64 ist eine vollständig umkehrbare, öffentliche Umschreibung. Es gibt keinen Schlüssel, kein Geheimnis, nichts. Jeder, der die Zeichenkette sieht, kann sie in Sekunden zurückverwandeln – jeder Browser, jedes Kommandozeilen-Tool, jeder Online-Decoder kann das.

Genau das ist beim JWT eine häufige Falle: Die Payload eines Tokens ist lesbar, nicht verschlüsselt. Sie enthält Claims wie Benutzer-ID, Rollen oder Ablaufzeit im Klartext – nur base64url-kodiert. Was ein JWT absichert, ist allein die Signatur im dritten Teil: Sie belegt, dass niemand Header oder Payload nachträglich verändert hat. Vertraulichkeit stellt sie nicht her. Wer sensible Daten in eine JWT-Payload schreibt, legt sie faktisch offen.

Merksatz: Base64 schafft Transportfähigkeit, nicht Geheimhaltung. Wer Daten schützen will, braucht Verschlüsselung (etwa AES oder TLS). Wer Integrität sichern will, braucht eine Signatur oder einen HMAC. Base64 leistet keines von beidem.

Häufige Fallstricke im Alltag

Der Klassiker ist die Verwechslung der Alphabete. Ein Dienst liefert Base64url, dein Decoder erwartet Standard-Base64 – und stolpert über ein - oder _, das im klassischen Alphabet keinen Wert hat. Umgekehrt genauso: Ein + aus Standard-Base64 ist in einer strikten Base64url-Prüfung ungültig. Viele Bibliotheken bieten getrennte Funktionen (base64_encode vs. eine url-safe Variante); die falsche zu erwischen, ist ein Einzeiler-Bug mit langer Fehlersuche.

Der zweite Fallstrick ist das Padding. Ein Base64url-String ohne = hat eine Länge modulo 4 von 2 oder 3 – ein Decoder, der stur ein Vielfaches von vier erwartet, wirft dann einen Fehler. Die saubere Lösung: vor dem Dekodieren die fehlenden = anhand der Länge ergänzen oder gleich einen toleranten Decoder nutzen.

Dritter Punkt: Zeilenumbrüche. Das ältere MIME-Base64 (RFC 2045) fügt nach 76 Zeichen einen Umbruch ein. In URLs, JWTs oder JSON haben solche Umbrüche nichts zu suchen – ein \n mitten im Token ist ein sicherer Weg zu einem ungültigen Wert. Achte darauf, dass deine Kodierung ohne Zeilenumbrüche läuft, wenn das Ergebnis in einen kompakten Kontext soll.

Kurz entscheiden: Standard oder url?

Die Faustregel ist überschaubar. Solange dein Base64 in einem »breiten« Textkanal bleibt – ein E-Mail-Body, ein XML-Feld, eine Konfigurationsdatei, eine Data-URL im HTML-Attribut – ist Standard-Base64 mit +, / und = die richtige und weitverbreitete Wahl. Hier stört nichts, und die meisten Werkzeuge erwarten genau dieses Alphabet.

Sobald der Wert aber in eine URL, einen Query-Parameter, einen Dateinamen oder ein JWT wandert, nimmst du Base64url – mit -, _ und in der Regel ohne Padding. So sparst du dir Prozent-Kodierung, vermeidest das Leerzeichen-Problem des + und die Pfad-Verwechslung des /. Und die dritte Regel gilt in beiden Varianten: Base64 ist kein Schutz – der Umschlag, nicht das Schloss.

Was Tools auf CalcSI helfen

Um Bytes gefahrlos in beide Richtungen umzuwandeln, nutzt du den Base64 Encoder/Decoder: Er zeigt dir sofort, wie aus Text die kodierte Zeichenkette wird – inklusive +, / und Padding – und dekodiert Standard- wie url-Varianten zurück. Willst du prüfen, wie ein Wert in einer Adresszeile aussieht, machst du ihn mit dem URL-Encoder/Decoder lesbar und erkennst, welche Zeichen prozent-kodiert würden und warum - und _ dort unauffällig durchrutschen. Steckt der Base64url-Teil in einem Token, zerlegst du es mit dem JWT-Decoder in Header, Payload und Signatur und siehst schwarz auf weiß, dass die Payload nur kodiert und nicht verschlüsselt ist. Und um sicherzugehen, dass eine dekodierte Datei unverändert ist, bildest du mit dem Hash-Generator eine Prüfsumme über das Original. Alle vier laufen komplett im Browser – deine Daten verlassen deinen Rechner nicht.

Kommentare