Base64-Kodierung in Java — java.util.Base64 Beispiele
Nutze das kostenlose Base64 Encode Online direkt im Browser – keine Installation erforderlich.
Base64 Encode Online online testen →Jedes Mal, wenn ich einen HTTP-Basic-Auth-Header verdrahte, ein Zertifikat in ein Kubernetes-Secret einbette oder binäre Daten über eine JSON-API schicke, ist der erste Schritt derselbe: Base64-kodiere die rohen Bytes in einen ASCII-sicheren String. Java macht das mit java.util.Base64 unkompliziert — der Standard-API, die seit Java 8 verfügbar ist und das veraltete sun.misc.BASE64Encoder abgelöst hat. Für eine schnelle Einzel-Kodierung ohne Code schreiben zu müssen, erledigt ToolDeck's Base64 Encoder das sofort im Browser. Dieser Leitfaden behandelt Base64.getEncoder(), getUrlEncoder(), getMimeEncoder(), Datei-Kodierung, Streaming mit wrap(OutputStream) sowie die Fehler, über die selbst erfahrene Java-Entwickler stolpern. Alle Beispiele kompilieren auf Java 8 bis Java 21+.
- ✓Base64.getEncoder().encodeToString(bytes) ist der Standard-Einzeiler — seit Java 8 im JDK enthalten, unverändert in Java 17 und 21.
- ✓Übergib StandardCharsets.UTF_8 immer explizit an String.getBytes() — fehlt die Angabe, wird der Plattform-Standard verwendet, der je nach JVM variiert.
- ✓getUrlEncoder() erzeugt URL-sichere Ausgabe (- statt +, _ statt /) und withoutPadding() entfernt abschließende =-Zeichen.
- ✓getMimeEncoder() fügt alle 76 Zeichen Zeilenumbrüche ein — erforderlich für E-Mail (MIME) und PEM-Zertifikatsformate.
- ✓Für große Dateien Base64.getEncoder().wrap(OutputStream) verwenden, um zu streamen, ohne die gesamte Datei in den Speicher zu laden.
Was ist Base64-Kodierung?
Base64 wandelt beliebige Binärdaten in einen String aus 64 druckbaren ASCII-Zeichen um: A-Z, a-z, 0-9, + und /. Jeweils 3 Eingabe-Bytes ergeben genau 4 Base64-Zeichen. Ist die Eingabelänge kein Vielfaches von 3, werden ein oder zwei = Auffüllzeichen angehängt. Die kodierte Ausgabe ist stets etwa 33 % größer als die Originaldaten.
Base64 ist keine Verschlüsselung. Jeder mit dem kodierten String kann ihn dekodieren. Der Zweck ist Transportsicherheit: HTTP-Header, JSON-Payloads, XML-Dokumente und E-Mail-Bodies sind textbasierte Protokolle, die rohe Binär-Bytes nicht ohne Datenverlust übertragen können. Typische Java-Anwendungsfälle sind HTTP-Basic-Authentication, das Einbetten von PEM-Zertifikaten, das Speichern von Binärdaten in Datenbanktext-Spalten und das Konstruieren von JWT-Token-Segmenten.
deploy-svc:sk_live_4eC39HqLyjWDarjtT1zdp7dc
ZGVwbG95LXN2Yzpza19saXZlXzRlQzM5SHFMeWpXRGFyanRUMXpkcDdkYw==
Base64.getEncoder().encodeToString() — Die Standard-API
java.util.Base64 wurde in Java 8 als offizieller Ersatz für sun.misc.BASE64Encoder eingeführt. Die Klasse stellt drei statische Factory-Methoden bereit — jede gibt eine Base64.Encoder Instanz zurück — die die drei in RFC 4648 definierten Base64-Varianten abdecken. Es wird keine Drittanbieter-Bibliothek benötigt. Keine Maven-Abhängigkeit. Einfach importieren und aufrufen.
Minimales Beispiel — Einen String kodieren
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class EncodeDemo {
public static void main(String[] args) {
String credentials = "monitoring-svc:9f2a7c4e-b1d8-4a3f";
byte[] credentialBytes = credentials.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(credentialBytes);
System.out.println(encoded);
// bW9uaXRvcmluZy1zdmM6OWYyYTdjNGUtYjFkOC00YTNm
}
}Der entscheidende Schritt, den viele Java-Entwickler beim ersten Mal übersehen: Ein String muss vor der Kodierung in byte[] konvertiert werden. Base64 arbeitet mit Bytes, nicht mit Zeichen. encodeToString() akzeptiert ein byte[] und gibt den Base64- String direkt zurück. Wird das kodierte Ergebnis als Bytes benötigt, verwende encode(byte[]) — das gibt ein byte[] der ASCII-kodierten Base64-Zeichen zurück, nützlich beim direkten Schreiben in einen OutputStream oder beim Aufbau binärer Protokollframes.
HTTP Basic Auth — Der häufigste Anwendungsfall
HTTP-Basic-Authentication ist wohl der häufigste Grund, warum Java-Entwickler auf Base64-Kodierung zurückgreifen. Die Spezifikation (RFC 7617) verlangt, dass der Credentials-String username:password Base64-kodiert und im Authorization-Header platziert wird. Ich habe gesehen, wie das unzählige Male falsch gemacht wurde — meistens durch das Vergessen des Doppelpunkt-Trennzeichens oder durch das separate Kodieren der Komponenten.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class BasicAuthExample {
public static void main(String[] args) throws Exception {
String username = "metrics-exporter";
String apiKey = "sk_live_4eC39HqLyjWDarjtT1zdp7dc";
// username:password → Base64
String credentials = username + ":" + apiKey;
String authHeader = "Basic " + Base64.getEncoder()
.encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/v2/metrics"))
.header("Authorization", authHeader)
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); // 200
}
}Roundtrip — Kodieren und Dekodieren
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class RoundTrip {
public static void main(String[] args) {
String original = "X-Correlation-ID: req_8a4f2c91-e7b3-4d56-9012-3f7a8b9c0d1e";
// Kodieren
String encoded = Base64.getEncoder()
.encodeToString(original.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// WC1Db3JyZWxhdGlvbi1JRDogcmVxXzhhNGYyYzkxLWU3YjMtNGQ1Ni05MDEyLTNmN2E4YjljMGQxZQ==
// Dekodieren
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println(original.equals(decoded)); // true
}
}java.util.Base64 API ist von Java 8 über Java 17 bis Java 21 identisch. Beim Aktualisieren der JDK-Version ist keine Migration nötig. Derselbe Code kompiliert und läuft auf jeder Version seit Java 8.Nicht-String-Daten kodieren — byte[], UUID und Timestamps
Base64-Kodierung in Java beginnt immer mit einem byte[]. Strings werden über getBytes(StandardCharsets.UTF_8) konvertiert, aber andere Typen benötigen zuerst einen Konvertierungsschritt. UUIDs, Timestamps und numerische Bezeichner müssen in eine String- oder Byte-Darstellung serialisiert werden, bevor sie Base64-kodiert werden können.
UUID — Als String-Darstellung kodieren
import java.util.Base64;
import java.util.UUID;
import java.nio.charset.StandardCharsets;
UUID sessionId = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
String encoded = Base64.getEncoder()
.encodeToString(sessionId.toString().getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// NmJhN2I4MTAtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4Kompakte UUID — Die rohen 16 Bytes kodieren
Für ein kürzeres kodiertes Ergebnis extrahiere die 128 Bits der UUID als 16 rohe Bytes, anstatt sie in ihre 36-Zeichen-String-Form zu konvertieren. Die Base64-Ausgabe schrumpft damit von 48 auf 24 Zeichen.
import java.nio.ByteBuffer;
import java.util.Base64;
import java.util.UUID;
UUID eventId = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
ByteBuffer buffer = ByteBuffer.wrap(new byte[16]);
buffer.putLong(eventId.getMostSignificantBits());
buffer.putLong(eventId.getLeastSignificantBits());
String compact = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(buffer.array());
System.out.println(compact);
// VQ6EAOKbQdSnFkRmVUQAAA
// 22 Zeichen vs. 48 für den String-basierten AnsatzTimestamp und gemischte Payload
import java.time.Instant;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
// Simuliert eine JWT-ähnliche Payload
String payload = String.format(
"{"sub":"usr_7b3c","iss":"auth.internal","iat":%d,"exp":%d}",
Instant.now().getEpochSecond(),
Instant.now().plusSeconds(3600).getEpochSecond()
);
String encoded = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(payload.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// eyJzdWIiOiJ1c3JfN2IzYyIsImlzcyI6ImF1dGguaW50ZXJuYWwiLCJpYXQiOj... (URL-sicher, kein Padding)toString() nicht auf einem byte[] auf und erwarte dessen Inhalt — das liefert den Identity-Hash des Arrays wie [B@6d06d69c. Verwende stattdessen new String(bytes, StandardCharsets.UTF_8) oder übergib das Byte-Array direkt an encodeToString().Base64.Encoder-Methoden Referenz
Die java.util.Base64 Klasse stellt drei Factory-Methoden bereit, die jeweils einen für eine bestimmte Variante konfigurierten Base64.Encoder zurückgeben. Die Encoder-Instanzen sind thread-safe und zustandslos — einmal erstellen und wiederverwenden.
Base64.getUrlEncoder() — URL-sichere Kodierung
Der URL-sichere Encoder verwendet ein alternatives Alphabet, bei dem + zu - und / zu _ wird, wie in RFC 4648 Abschnitt 5 definiert. Das ist relevant, wenn der Base64-String in einem URL-Abfrageparameter, einem Dateinamen oder einem Cookie-Wert erscheint — Standard-Base64-Zeichen kollidieren mit URL-Trennzeichen und reservierten Dateisystem-Zeichen.
import java.util.Base64; import java.nio.charset.StandardCharsets; String redirectUri = "https://app.internal/callback?state=auth_pending&nonce=9f2a7c"; byte[] data = redirectUri.getBytes(StandardCharsets.UTF_8); // Standard-Encoder — enthält + und /, die URLs beschädigen String standard = Base64.getEncoder().encodeToString(data); System.out.println(standard); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s/c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw== // URL-sicherer Encoder — sicher für Abfrageparameter und Dateinamen String urlSafe = Base64.getUrlEncoder().encodeToString(data); System.out.println(urlSafe); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw== // URL-sicher ohne Padding — für JWTs und kompakte Tokens String noPadding = Base64.getUrlEncoder().withoutPadding().encodeToString(data); System.out.println(noPadding); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw
Die withoutPadding() Variante entfernt die abschließenden = Zeichen. JWT-Spezifikationen verlangen URL-sicheres Base64 ohne Padding für die Header- und Payload-Segmente, daher ist getUrlEncoder().withoutPadding() genau der richtige Aufruf beim manuellen Erstellen oder Manipulieren von JWT-Tokens.
withoutPadding()-Methode gibt eine neue Encoder-Instanz zurück — sie verändert das Original nicht. Beide können in static final-Feldern gespeichert und thread-sicher wiederverwendet werden.Aus Datei und API-Antwort kodieren
Die zwei häufigsten realen Szenarien für Base64-Kodierung in Java: eine Binärdatei vom Datenträger lesen (Zertifikate, Bilder, Konfigurationspakete) und Daten aus einer HTTP-Antwort kodieren.
Eine Datei als Base64 kodieren
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
public class FileEncoder {
public static void main(String[] args) {
try {
byte[] fileBytes = Files.readAllBytes(Path.of("certs/server.pem"));
String encoded = Base64.getEncoder().encodeToString(fileBytes);
System.out.printf("Original: %d bytes%n", fileBytes.length);
System.out.printf("Kodiert: %d chars%n", encoded.length());
// Kodierter Inhalt in eine Textdatei schreiben
Files.writeString(
Path.of("certs/server.pem.b64"),
encoded
);
} catch (java.io.IOException e) {
System.err.println("Datei konnte nicht gelesen werden: " + e.getMessage());
}
}
}Eine API-Antwort kodieren
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
public class ApiEncoder {
public static void main(String[] args) {
try {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/v2/reports/weekly.pdf"))
.header("Authorization", "Bearer tok_8f2a9c3d")
.build();
HttpResponse<byte[]> response = client.send(
request, HttpResponse.BodyHandlers.ofByteArray()
);
if (response.statusCode() == 200) {
String encoded = Base64.getEncoder()
.encodeToString(response.body());
System.out.printf("Kodiert %d bytes → %d chars%n",
response.body().length, encoded.length());
} else {
System.err.printf("HTTP %d: %s%n",
response.statusCode(),
new String(response.body()));
}
} catch (Exception e) {
System.err.println("Anfrage fehlgeschlagen: " + e.getMessage());
}
}
}Kurzer Hinweis vor dem CLI-Abschnitt: wenn du nur eine Datei oder API-Antwort einfügen und die Base64-Ausgabe erhalten möchtest, ohne Code zu schreiben, verarbeitet der Online Base64 Encoder sowohl Text- als auch Binäreingaben.
Base64-Kodierung in der Kommandozeile
Manchmal muss man einfach einen String oder eine Datei im Terminal kodieren — kein Java-Projekt, keine IDE, kein Build-Schritt. Die meisten Unix-Systeme liefern einen base64 Befehl mit, und wer ein JDK installiert hat, kann jshell für einen Java-nativen Ansatz nutzen.
# macOS / Linux — einen String kodieren
echo -n "deploy-bot:sk_prod_9f2a7c4e" | base64
# ZGVwbG95LWJvdDpza19wcm9kXzlmMmE3YzRl
# Eine Datei kodieren
base64 < certs/server.pem > certs/server.pem.b64
# Mit jshell (JDK 9+)
echo 'System.out.println(java.util.Base64.getEncoder().encodeToString("deploy-bot:sk_prod_9f2a7c4e".getBytes()))' | jshell -
# Mit java direkt als Einzeiler
java -e 'System.out.println(java.util.Base64.getEncoder().encodeToString(args[0].getBytes()))' "my-secret"
# Hinweis: java -e erfordert JDK 23+ (JEP 477)Der jshell-Ansatz ist besonders nützlich, wenn man sicherstellen möchte, dass der Java-Code dieselbe Ausgabe wie ein Unix-Tool produziert, oder beim Debuggen einer Abweichung zwischen dem, was der eigene Service sendet, und dem, was der Empfänger erwartet. Ich habe dafür einen Shell-Alias.
base64-Befehl -D zum Dekodieren. Auf Linux (GNU coreutils) wird -d verwendet. Das Kodierverhalten ist auf beiden identisch. Das Flag -w 0 unter Linux deaktiviert den Zeilenumbruch in der Ausgabe, was beim Weiterleiten an andere Befehle in der Regel gewünscht ist.Apache Commons Codec — Hochperformante Alternative
Für die meisten Anwendungen ist java.util.Base64 schnell genug. Werden jedoch Millionen von Kodieroperationen in einer engen Schleife verarbeitet — etwa in Log-Ingestion-Pipelines oder Hochdurchsatz-Message-Brokern — lohnt sich ein Benchmark mit Apache Commons Codec. Die Bibliothek existiert schon lange vor Java 8 und bietet eine bewährte Alternative mit einer etwas anderen API.
// Maven: org.apache.commons:commons-codec:1.17.0
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
byte[] telemetryPayload = ("{"service":"metrics-collector","
+ ""host":"prod-east-07","
+ ""cpu_pct":72.4,"
+ ""mem_mb":3891,"
+ ""timestamp":1710523200}")
.getBytes(StandardCharsets.UTF_8);
// Standard-Kodierung
String encoded = Base64.encodeBase64String(telemetryPayload);
// URL-sichere Kodierung
String urlSafe = Base64.encodeBase64URLSafeString(telemetryPayload);
// Prüfen, ob ein String gültiges Base64 ist
boolean valid = Base64.isBase64(encoded);
System.out.println(valid); // trueApache Commons Codec stellt außerdem Base64OutputStream und Base64InputStream für Streaming-Szenarien bereit und enthält eine Validierungsmethode, die dem JDK-Encoder fehlt. Ist Commons Codec bereits im Dependency-Baum vorhanden (es wird mit vielen Apache-Projekten mitgeliefert), spricht nichts dagegen, es zu verwenden.
Guava BaseEncoding
Googles Guava-Bibliothek enthält BaseEncoding, das eine fluent API für Base64 mit konfigurierbaren Zeilentrennzeichen, Padding-Steuerung und Unterstützung für Standard- und URL-sichere Alphabete bietet. Die API liest sich klar, aber Guava (ca. 3 MB) allein für Base64-Kodierung hinzuzufügen ist übertrieben. Wenn Guava bereits im Projekt für Collections oder Caching-Utilities vorhanden ist, ist die Encoding-API ein netter Bonus.
// Maven: com.google.guava:guava:33.1.0-jre
import com.google.common.io.BaseEncoding;
import java.nio.charset.StandardCharsets;
byte[] webhookPayload = ("{"event":"deployment.completed","
+ ""repo":"payments-api","
+ ""sha":"a7f2c91e4b3d","
+ ""environment":"production"}")
.getBytes(StandardCharsets.UTF_8);
// Standard Base64
String standard = BaseEncoding.base64().encode(webhookPayload);
// URL-sicher
String urlSafe = BaseEncoding.base64Url().encode(webhookPayload);
// Ohne Padding
String noPad = BaseEncoding.base64Url().omitPadding().encode(webhookPayload);
// Mit Zeilentrennzeichen (PEM-Stil)
String wrapped = BaseEncoding.base64()
.withSeparator("\n", 64)
.encode(webhookPayload);Base64.getMimeEncoder() — MIME- und PEM-Ausgabe mit Zeilenumbrüchen
Der MIME-Encoder fügt alle 76 Zeichen \r\n Zeilenumbrüche ein, entsprechend der MIME-Spezifikation (RFC 2045). PEM-Zertifikate, S/MIME-E-Mail-Anhänge und einige Legacy-APIs erwarten dieses Format. Die Standard- und URL-sicheren Encoder erzeugen eine einzige zusammenhängende Zeile — wird deren Ausgabe an ein System übergeben, das zeilenumbrochenes Base64 erwartet, kann das still fehlschlagen oder die Daten ablehnen.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
// Simuliert den Body eines PEM-Zertifikats
byte[] certData = new byte[256]; // In der Praxis aus einer .der-Datei lesen
new java.security.SecureRandom().nextBytes(certData);
// Standard-MIME-Encoder — 76 Zeichen pro Zeile, \r\n als Trennzeichen
String mimeEncoded = Base64.getMimeEncoder().encodeToString(certData);
System.out.println(mimeEncoded);
// QYx2K3p8Xg7JmN1R+wFkLd... (76 Zeichen)
// Ht5Bv9CzAq0PnSjYl8WxUe... (76 Zeichen)
// ...
// Benutzerdefinierter MIME-Encoder — 64 Zeichen pro Zeile (PEM-Standard), \n als Trennzeichen
Base64.Encoder pemEncoder = Base64.getMimeEncoder(64, new byte[]{'\n'});
String pemBody = pemEncoder.encodeToString(certData);
System.out.println("-----BEGIN CERTIFICATE-----");
System.out.println(pemBody);
System.out.println("-----END CERTIFICATE-----");getMimeEncoder() nicht für JWT-Tokens, HTTP-Header oder URL-Parameter. Die Zeilenumbrüche beschädigen die Daten in diesen Kontexten. Verwende stattdessen getEncoder() oder getUrlEncoder().Große Dateien streamen mit Base64.getEncoder().wrap()
Eine gesamte Datei mit Files.readAllBytes() in ein byte[] zu laden funktioniert bei kleinen Dateien, aber bei Dateien über 50–100 MB droht ein OutOfMemoryError. Das JDK stellt Base64.getEncoder().wrap(OutputStream) bereit, das einen OutputStream zurückgibt, der Daten beim Schreiben unmittelbar kodiert. Die kodierten Bytes fließen durch zum darunterliegenden Stream, ohne die gesamte Eingabe zu puffern.
import java.io.*;
import java.nio.file.*;
import java.util.Base64;
public class StreamingEncoder {
public static void main(String[] args) throws IOException {
Path inputPath = Path.of("backups/database-export.sql.gz");
Path outputPath = Path.of("backups/database-export.sql.gz.b64");
try (
InputStream in = Files.newInputStream(inputPath);
OutputStream fileOut = Files.newOutputStream(outputPath);
OutputStream base64Out = Base64.getEncoder().wrap(fileOut)
) {
byte[] buffer = new byte[8192];
int bytesRead;
long totalBytes = 0;
while ((bytesRead = in.read(buffer)) != -1) {
base64Out.write(buffer, 0, bytesRead);
totalBytes += bytesRead;
}
System.out.printf("Streamed %d bytes through Base64 encoder%n", totalBytes);
}
// Das Schließen von base64Out schreibt die abschließenden Padding-Bytes automatisch
}
}Der try-with-resources-Block übernimmt Flush und Close. Ein Detail, das viele überrascht: Das abschließende Base64-Padding wird erst geschrieben, wenn der umschließende OutputStream geschlossen wird. Wird das vergessen (oder nur der äußere Stream geschlossen), fehlen die letzten Zeichen der kodierten Ausgabe.
In einen Netzwerk-Socket streamen
Die wrap() Methode funktioniert mit jedem OutputStream — Dateiausgabe, Socket-Ausgabe, HTTP-Response-Body, sogar ByteArrayOutputStream. Hier ein Beispiel, das Base64-kodierte Daten direkt in einen In-Memory-Puffer schreibt — nützlich für Unit-Tests oder das Aufbauen von Payloads, die über HTTP gesendet werden:
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try (OutputStream encoder = Base64.getEncoder().wrap(buffer)) {
// Daten in Chunks schreiben — simuliert das Lesen aus einem Stream
encoder.write("chunk-1:telemetry-data-".getBytes(StandardCharsets.UTF_8));
encoder.write("chunk-2:more-payload-".getBytes(StandardCharsets.UTF_8));
encoder.write("chunk-3:final-segment".getBytes(StandardCharsets.UTF_8));
}
String encoded = buffer.toString(StandardCharsets.UTF_8);
System.out.println(encoded);
// Y2h1bmstMTp0ZWxlbWV0cnktZGF0YS1jaHVuay0yOm1vcmUtcGF5bG9hZC1jaHVuay0zOmZpbmFsLXNlZ21lbnQ=
// Roundtrip verifizieren
byte[] decoded = Base64.getDecoder().decode(encoded);
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// chunk-1:telemetry-data-chunk-2:more-payload-chunk-3:final-segmentBufferedInputStream und ist ein gutes Gleichgewicht zwischen Speicherverbrauch und System-Call-Overhead. Kleinere Puffer erhöhen die Anzahl der Lese-/Schreibaufrufe; größere Puffer verschwenden Speicher ohne nennenswerten Durchsatzgewinn.Thread-sichere Encoder-Instanzen — Speichern und Wiederverwenden
Der von den Factory-Methoden zurückgegebene Base64.Encoder ist unveränderlich und thread-sicher. Ein Aufruf von Base64.getEncoder() bei jeder Kodieroperation erstellt jedes Mal ein neues Objekt. Die JVM wird das wahrscheinlich wegoptimieren, aber den Encoder in einem static final Feld zu speichern macht die Absicht deutlich und vermeidet unnötige Allokierungen in kritischen Pfaden.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class TokenService {
// Einmal erstellen, überall wiederverwenden — thread-sicher
private static final Base64.Encoder STANDARD = Base64.getEncoder();
private static final Base64.Encoder URL_SAFE = Base64.getUrlEncoder().withoutPadding();
private static final Base64.Encoder MIME = Base64.getMimeEncoder();
public static String encodeForHeader(String value) {
return STANDARD.encodeToString(value.getBytes(StandardCharsets.UTF_8));
}
public static String encodeForUrl(byte[] data) {
return URL_SAFE.encodeToString(data);
}
public static String encodeForEmail(byte[] attachment) {
return MIME.encodeToString(attachment);
}
}Dieses Muster ist besonders nützlich in Spring-Boot-Services, bei denen eine Utility-Klasse die Kodierung über mehrere Controller oder Service-Methoden hinweg übernimmt. Der withoutPadding() Aufruf gibt eine neue Encoder-Instanz zurück, sodass gepolsterte und ungepolsterte Varianten als separate Felder gespeichert werden können. Jeder Aufruf von encodeToString() oder encode() ist zustandslos — keine Synchronisierung nötig, kein geteilter veränderbarer Zustand.
Häufige Fehler
Problem: String.getBytes() ohne Charset-Argument verwendet die plattformspezifische Standardkodierung: windows-1252 unter Windows, UTF-8 auf den meisten Linux-Systemen und variierend unter macOS. Derselbe Code erzeugt auf verschiedenen Maschinen unterschiedliche Base64-Ausgaben.
Lösung: Übergib StandardCharsets.UTF_8 immer explizit.
String text = "Ключ доступа: prod-east"; byte[] bytes = text.getBytes(); // Plattform-Standard — unvorhersehbar String encoded = Base64.getEncoder().encodeToString(bytes);
String text = "Ключ доступа: prod-east"; byte[] bytes = text.getBytes(StandardCharsets.UTF_8); String encoded = Base64.getEncoder().encodeToString(bytes);
Problem: Base64.getEncoder() gibt + und /-Zeichen aus. In einem URL-Query-String wird + als Leerzeichen und / als Pfadtrennzeichen interpretiert, was den Wert auf der Empfängerseite lautlos beschädigt.
Lösung: Verwende Base64.getUrlEncoder() für jeden Wert, der in einer URL erscheinen wird.
// Token im URL-Abfrageparameter — wird beschädigt
String token = Base64.getEncoder()
.encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;// URL-sichere Kodierung — keine + oder /-Zeichen
String token = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;Problem: Kodierung mit getUrlEncoder() und Dekodierung mit getDecoder() (oder umgekehrt) wirft eine IllegalArgumentException, weil - und _ im Standard-Base64-Alphabet ungültig sind und + und / im URL-sicheren Alphabet nicht vorkommen.
Lösung: Dekodiere immer mit dem passenden Decoder: getUrlDecoder() für URL-sicher, getDecoder() für Standard.
String encoded = Base64.getUrlEncoder()
.encodeToString(data);
// Später...
byte[] decoded = Base64.getDecoder() // FALSCHER Decoder
.decode(encoded);
// IllegalArgumentException wenn encoded - oder _ enthältString encoded = Base64.getUrlEncoder()
.encodeToString(data);
// Später...
byte[] decoded = Base64.getUrlDecoder() // passender Decoder
.decode(encoded);Problem: Der Streaming-Encoder puffert bis zu 2 Eingabe-Bytes und wartet auf eine vollständige 3-Byte-Gruppe. Wird der umschließende OutputStream nicht geschlossen, werden die letzten 1–4 Base64-Zeichen (einschließlich Padding) nie geschrieben.
Lösung: Verwende try-with-resources oder rufe close() explizit auf dem umschließenden Stream auf, bevor die Ausgabe gelesen wird.
ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream b64os = Base64.getEncoder().wrap(baos); b64os.write(data); // baos.toString() ist UNVOLLSTÄNDIG — letzte Bytes fehlen
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream b64os = Base64.getEncoder().wrap(baos)) {
b64os.write(data);
} // close() schreibt das abschließende Padding
String encoded = baos.toString(); // vollständigBase64-Kodierungsmethoden — Vergleich
Für die meisten Projekte ist java.util.Base64 die richtige Wahl. Keine Abhängigkeiten, im JDK eingebaut, thread-sicher und deckt alle drei RFC 4648-Varianten ab. Apache Commons Codec empfiehlt sich nur, wenn es bereits im Classpath vorhanden ist und die isBase64() Validierungsmethode oder das Streaming mit Base64OutputStream benötigt wird. Guavas BaseEncoding ist eine vernünftige Option, wenn das Projekt bereits von Guava abhängt, aber eine 3-MB-Abhängigkeit nur für Base64 lässt sich kaum rechtfertigen.
Drei Szenarien, drei Empfehlungen: Normaler Webservice, der Basic Auth oder JWT-Kodierung benötigt? Beim JDK bleiben. Legacy-Projekt, das Commons Codec bereits über Spring oder Apache HTTP Client einbindet? Verwenden — kein Grund, zwei Base64-Bibliotheken im Classpath zu haben. Projekt, das Guava für Caching und Collections nutzt? BaseEncoding für die saubere fluent API wählen. Niemals eine Bibliothek nur für Base64-Kodierung hinzufügen — die JDK-Version ist seit 2014 gut genug.
Um ein kodiertes Ergebnis schnell zu überprüfen, ohne Java-Code auszuführen, einfach in den Base64 Encoder einfügen und bestätigen, dass die Ausgabe mit dem übereinstimmt, was der Code erzeugt.
Häufig gestellte Fragen
Wie kodiere ich einen String in Java als Base64?
Konvertiere den String zunächst mit getBytes(StandardCharsets.UTF_8) in Bytes und übergib das Byte-Array dann an Base64.getEncoder().encodeToString(). Gib UTF-8 immer explizit an — ein Aufruf von getBytes() ohne Charset-Argument verwendet den plattformspezifischen Standard, der je nach Betriebssystem und JVM-Konfiguration variiert.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
String payload = "grant_type=client_credentials&scope=read:metrics";
String encoded = Base64.getEncoder()
.encodeToString(payload.getBytes(StandardCharsets.UTF_8));
// Z3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMmc2NvcGU9cmVhZDptZXRyaWNzWas ist der Unterschied zwischen Base64.getEncoder() und Base64.getUrlEncoder()?
Beide kodieren in Base64, aber getUrlEncoder() verwendet das URL-sichere Alphabet aus RFC 4648 Abschnitt 5. Es ersetzt + durch - und / durch _, sodass die Ausgabe in URLs und Dateinamen ohne Percent-Encoding verwendet werden kann. Der Standard-Encoder verwendet + und /, die mit URL-Abfrageparametern und Pfadsegmenten kollidieren.
byte[] data = "subject=usr_7b3c&role=admin".getBytes(StandardCharsets.UTF_8); String standard = Base64.getEncoder().encodeToString(data); // c3ViamVjdD11c3JfN2IzYyZyb2xlPWFkbWlu String urlSafe = Base64.getUrlEncoder().encodeToString(data); // c3ViamVjdD11c3JfN2IzYyZyb2xlPWFkbWlu // (same here, but with + → - and / → _ when those chars appear)
Ist java.util.Base64 in Java 8 und Java 17 identisch?
Ja. Die java.util.Base64 API hat sich seit ihrer Einführung in Java 8 nicht verändert. Die Klasse, ihre verschachtelten Encoder- und Decoder-Klassen sowie alle Factory-Methoden (getEncoder, getUrlEncoder, getMimeEncoder) sind über Java 8, 11, 17 und 21 hinweg identisch. Beim Aktualisieren der JDK-Version sind keine Migration oder Codeänderungen erforderlich.
// Dieser Code kompiliert und läuft identisch auf Java 8 bis Java 21+
import java.util.Base64;
import java.nio.charset.StandardCharsets;
String encoded = Base64.getEncoder()
.encodeToString("stable-api".getBytes(StandardCharsets.UTF_8));
System.out.println(encoded); // c3RhYmxlLWFwaQ==Wie kodiere ich eine Datei als Base64 in Java?
Lese die Datei mit Files.readAllBytes(Path) in ein Byte-Array und übergib es an Base64.getEncoder().encodeToString(). Für große Dateien, die nicht vollständig in den Speicher geladen werden sollen, verwende Base64.getEncoder().wrap(OutputStream), um die kodierte Ausgabe zu streamen.
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
byte[] fileBytes = Files.readAllBytes(Path.of("config/tls-cert.pem"));
String encoded = Base64.getEncoder().encodeToString(fileBytes);Warum wurde sun.misc.BASE64Encoder als veraltet markiert?
sun.misc.BASE64Encoder war eine interne JDK-Klasse, die nie Teil der öffentlichen API war. Sie befand sich im sun.misc-Paket, vor dessen Verwendung Oracle ausdrücklich warnte. Java 8 führte java.util.Base64 als offiziellen, öffentlichen und unterstützten Ersatz ein. Seit Java 9 und dem Modulsystem erzeugt der Zugriff auf sun.misc-Klassen je nach JDK-Konfiguration Warnungen oder Fehler.
// Alte Methode — NICHT verwenden, in modernen JDKs entfernt // import sun.misc.BASE64Encoder; // String encoded = new BASE64Encoder().encode(data); // Richtige Methode seit Java 8 import java.util.Base64; String encoded = Base64.getEncoder().encodeToString(data);
Wie führe ich einen Base64-Roundtrip (Kodierung und Dekodierung) in Java durch?
Kodiere mit Base64.getEncoder().encodeToString(bytes) und dekodiere mit Base64.getDecoder().decode(encodedString). Konvertiere das dekodierte Byte-Array mit new String(bytes, StandardCharsets.UTF_8) zurück in einen String. Der Roundtrip bewahrt die Originaldaten exakt — sofern du für getBytes() und new String() denselben Zeichensatz verwendest.
import java.util.Base64; import java.nio.charset.StandardCharsets; // Kodieren String original = "session_token=eyJhbGciOiJSUzI1NiJ9"; byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8); String encoded = Base64.getEncoder().encodeToString(originalBytes); // Dekodieren byte[] decodedBytes = Base64.getDecoder().decode(encoded); String decoded = new String(decodedBytes, StandardCharsets.UTF_8); System.out.println(original.equals(decoded)); // true
Verwandte Tools
- Base64 Decoder — Base64-Strings zurück in ihren ursprünglichen Text oder ihre binäre Form dekodieren — die umgekehrte Operation der Kodierung.
- URL Encoder — Strings für die sichere Verwendung in URLs percent-kodieren — anders als URL-sicheres Base64-Encoding, aber häufig gemeinsam eingesetzt.
- JWT Decoder — JWT-Tokens untersuchen, deren Header- und Payload-Segmente Base64url-kodiertes JSON enthalten — ohne Bibliothek dekodieren.
- JSON Formatter — JSON-Payloads vor oder nach der Base64-Kodierung formatiert ausgeben — nützlich beim Debuggen von API-Integrationen.
Aisha is a Java engineer specialising in application security, Spring Security, and API design. She has worked on identity and access management systems, OAuth 2.0 integrations, and microservice security at scale. She writes about secure Java coding practices, token validation, cryptographic utilities, and the Spring ecosystem from a security-first perspective.
Pavel is a backend engineer with deep roots in the JVM ecosystem, working primarily with Java and Kotlin. He has extensive experience building data-intensive services and integrating third-party APIs at scale. He writes about modern Java features, the Jackson ecosystem, serialisation patterns, and practical approaches to keeping large codebases maintainable.