Base64-Kodierung in Java — java.util.Base64 Beispiele

·Java Security & API Engineer·Geprüft vonPavel Novak·Veröffentlicht

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.

Before · text
After · text
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

Java 8+
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.

Java — HTTP Basic Auth header
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

Java 8+ — encode and decode round-trip
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
    }
}
Hinweis:Die 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

Java — Base64 encoding a UUID
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);
// NmJhN2I4MTAtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4

Kompakte 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.

Java — compact UUID encoding
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 Ansatz

Timestamp und gemischte Payload

Java — encoding a JSON-like payload with timestamp
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)
Warnung:Rufe 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.

Methode
Typ
Beschreibung
getEncoder()
Base64.Encoder
Gibt einen einfachen RFC 4648-Encoder zurück, der das Standardalphabet verwendet (A-Z, a-z, 0-9, +, /)
getUrlEncoder()
Base64.Encoder
Gibt einen Encoder zurück, der das URL-sichere Alphabet verwendet (- statt +, _ statt /)
getMimeEncoder()
Base64.Encoder
Gibt einen MIME-Encoder zurück, der alle 76 Zeichen \r\n-Zeilenumbrüche einfügt
getMimeEncoder(lineLength, lineSeparator)
Base64.Encoder
MIME-Encoder mit benutzerdefinierter Zeilenlänge und Trennzeichen-Bytes
encoder.withoutPadding()
Base64.Encoder
Gibt einen Encoder zurück, der abschließende =-Auffüllzeichen weglässt
encoder.encode(byte[])
byte[]
Kodiert ein Byte-Array und gibt das kodierte Byte-Array zurück
encoder.encodeToString(byte[])
String
Kodiert ein Byte-Array und gibt direkt einen kodierten String zurück
encoder.wrap(OutputStream)
OutputStream
Umschließt einen OutputStream für Streaming-Base64-Kodierung

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.

Java — URL-safe Base64 encoding
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.

Hinweis:Die 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

Java — encoding a file
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

Java 11+ — encoding an HTTP response
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.

Bash — command-line Base64 encoding
# 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.

Hinweis:Auf macOS verwendet der 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.

Java — Apache Commons Codec
// 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);  // true

Apache 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.

Java — Guava BaseEncoding
// 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.

Java — MIME Base64 encoding
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-----");
Warnung:Verwende 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.

Java — streaming Base64 encoding
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:

Java — streaming to ByteArrayOutputStream
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-segment
Hinweis:Die Puffergröße im Streaming-Beispiel (8192 Bytes) ist nicht zufällig. Sie entspricht der Standard-Puffergröße von BufferedInputStream 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.

Java — reusable encoder instances
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

getBytes() ohne Charset-Angabe aufrufen

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.

Before · Java
After · Java
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);
Den Standard-Encoder für URL-Parameter verwenden

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.

Before · Java
After · Java
// 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;
Mit der falschen Encoder-Variante dekodieren

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.

Before · Java
After · Java
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Später...
byte[] decoded = Base64.getDecoder()  // FALSCHER Decoder
    .decode(encoded);
// IllegalArgumentException wenn encoded - oder _ enthält
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Später...
byte[] decoded = Base64.getUrlDecoder()  // passender Decoder
    .decode(encoded);
Den wrap()-OutputStream nicht schließen

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.

Before · Java
After · Java
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ändig

Base64-Kodierungsmethoden — Vergleich

Methode
URL-sicher
Streaming
Zeilenumbrüche
Eigene Typen
Installation nötig
Base64.getEncoder()
✓ (wrap)
Nein (JDK 8+)
Base64.getUrlEncoder()
✓ (wrap)
Nein (JDK 8+)
Base64.getMimeEncoder()
✓ (wrap)
✓ (76 Zeichen)
Nein (JDK 8+)
Apache Commons Codec
Maven-Abhängigkeit
Guava BaseEncoding
✓ (konfigurierbar)
Maven-Abhängigkeit
jcmd / CLI base64
✓ (pipe)
N/A
System-Installation

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.

Java
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));
// Z3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMmc2NvcGU9cmVhZDptZXRyaWNz

Was 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.

Java
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.

Java
// 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.

Java
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.

Java
// 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.

Java
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 DecoderBase64-Strings zurück in ihren ursprünglichen Text oder ihre binäre Form dekodieren — die umgekehrte Operation der Kodierung.
  • URL EncoderStrings für die sichere Verwendung in URLs percent-kodieren — anders als URL-sicheres Base64-Encoding, aber häufig gemeinsam eingesetzt.
  • JWT DecoderJWT-Tokens untersuchen, deren Header- und Payload-Segmente Base64url-kodiertes JSON enthalten — ohne Bibliothek dekodieren.
  • JSON FormatterJSON-Payloads vor oder nach der Base64-Kodierung formatiert ausgeben — nützlich beim Debuggen von API-Integrationen.
Auch verfügbar in:JavaScriptPython
AO
Aisha OseiJava Security & API Engineer

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.

PN
Pavel NovakTechnischer Prüfer

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.