Kódování Base64 v Javě — Příklady java.util.Base64

·Java Security & API Engineer·ZkontrolovánoPavel Novak·Publikováno

Používejte bezplatný Base64 Encode Online přímo v prohlížeči — bez instalace.

Vyzkoušet Base64 Encode Online online →

Pokaždé, když nastavuji HTTP Basic Auth hlavičku, vkládám certifikát do Kubernetes secretu nebo posílám binární data přes JSON API, první krok je vždy stejný: base64 kódování surových bajtů do ASCII-bezpečného řetězce. Java to umožňuje snadno pomocí java.util.Base64, standardního API dostupného od Javy 8, které nahradilo zastaralý sun.misc.BASE64Encoder. Pro rychlé jednorázové kódování bez psaní kódu Base64 Encoder od ToolDeck to zvládne okamžitě v prohlížeči. Tento průvodce pokrývá Base64.getEncoder(), getUrlEncoder(), getMimeEncoder(), kódování souborů, streamování pomocí wrap(OutputStream) a chyby, na které narazí i zkušení Java vývojáři. Všechny příklady jsou kompatibilní s Javou 8 až Java 21+.

  • Base64.getEncoder().encodeToString(bytes) je standardní jednořádkové řešení — součást JDK od Javy 8, nezměněno v Javě 17 ani 21.
  • Před kódováním vždy předávejte StandardCharsets.UTF_8 metodě String.getBytes() — vynechání způsobí použití výchozí platformní sady, která se liší mezi JVM.
  • getUrlEncoder() produkuje URL-bezpečný výstup (- místo +, _ místo /) a withoutPadding() odstraní znaky = na konci.
  • getMimeEncoder() vkládá zalomení řádků každých 76 znaků — vyžadováno pro e-mailový formát (MIME) a PEM certifikáty.
  • Pro velké soubory použijte Base64.getEncoder().wrap(OutputStream) pro streamování bez načtení celého souboru do paměti.

Co je Base64 kódování?

Base64 převádí libovolná binární data na řetězec složený z 64 tisknutelných ASCII znaků: A-Z, a-z, 0-9, + a /. Každé 3 bajty vstupu produkují přesně 4 Base64 znaky. Pokud délka vstupu není násobkem 3, přidají se jeden nebo dva znaky = jako padding. Zakódovaný výstup je vždy přibližně o 33 % větší než původní data.

Base64 není šifrování. Každý, kdo má zakódovaný řetězec, jej může dekódovat. Účelem je bezpečnost přenosu: HTTP hlavičky, JSON payloady, XML dokumenty a e-mailová těla jsou textové protokoly, které nemohou přenášet surové binární bajty bez poškození. Typické použití v Javě zahrnuje HTTP Basic Authentication, vkládání PEM certifikátů, ukládání binárních dat do textových sloupců databáze a sestavování segmentů JWT tokenů.

Before · text
After · text
deploy-svc:sk_live_4eC39HqLyjWDarjtT1zdp7dc
ZGVwbG95LXN2Yzpza19saXZlXzRlQzM5SHFMeWpXRGFyanRUMXpkcDdkYw==

Base64.getEncoder().encodeToString() — Standardní API

java.util.Base64 bylo zavedeno v Javě 8 jako oficiální náhrada za sun.misc.BASE64Encoder. Třída poskytuje tři statické tovární metody — každá vrací instanci vnořené třídy Base64.Encoder — pokrývající tři varianty Base64 definované v RFC 4648. Žádná knihovna třetí strany není potřeba. Žádná Maven závislost. Stačí importovat a zavolat.

Minimální příklad — zakódování řetězce

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
    }
}

Klíčový krok, který většina Java vývojářů při prvním pokusu přehlédne: String musí být před kódováním převeden na byte[]. Base64 pracuje s bajty, nikoli se znaky. encodeToString() přijímá byte[] a vrací přímo Base64 String. Pokud potřebujete zakódovaný výsledek jako bajty, použijte encode(byte[]) — vrátí byte[] ASCII-zakódovaných Base64 znaků, užitečné při přímém zápisu do OutputStream nebo sestavování rámců binárního protokolu.

HTTP Basic Auth — nejčastější případ použití

HTTP Basic Authentication je pravděpodobně nejčastějším důvodem, proč Java vývojáři sahají po Base64 kódování. Specifikace (RFC 7617) vyžaduje, aby byl řetězec přihlašovacích údajů username:password zakódován do Base64 a umístěn do hlavičky Authorization. Viděl jsem to dělat špatně nesčetněkrát — nejčastěji zapomenutím oddělovače dvojtečky nebo oddělené kódování jednotlivých částí.

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
    }
}

Zpětná konverze — kódování a dekódování

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";

        // Kódování
        String encoded = Base64.getEncoder()
            .encodeToString(original.getBytes(StandardCharsets.UTF_8));
        System.out.println(encoded);
        // WC1Db3JyZWxhdGlvbi1JRDogcmVxXzhhNGYyYzkxLWU3YjMtNGQ1Ni05MDEyLTNmN2E4YjljMGQxZQ==

        // Dekódování
        byte[] decodedBytes = Base64.getDecoder().decode(encoded);
        String decoded = new String(decodedBytes, StandardCharsets.UTF_8);

        System.out.println(original.equals(decoded));  // true
    }
}
Poznámka:API java.util.Base64 je identické od Javy 8 přes Javu 17 až po Javu 21. Při aktualizaci JDK není nutná žádná migrace. Stejný kód se kompiluje a spouští na libovolné verzi od Javy 8.

Kódování dat jiných typů — byte[], UUID a časová razítka

Base64 kódování v Javě vždy začíná s byte[]. Řetězce se převádějí přes getBytes(StandardCharsets.UTF_8), ale jiné typy vyžadují krok konverze. UUID, časová razítka a číselné identifikátory musí být serializovány do řetězcové nebo bajtové reprezentace, než je lze Base64-zakódovat.

UUID — kódování jako řetězcová reprezentace

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

Kompaktní UUID — kódování jako 16 surových bajtů

Pokud chcete kratší zakódovaný výsledek, extrahujte 128 bitů UUID jako 16 surových bajtů místo převodu na 36znakový řetězec. Base64 výstup se zkrátí ze 48 znaků na 24.

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 znaků oproti 48 u přístupu přes řetězec

Časové razítko a smíšená data

Java — encoding a JSON-like payload with timestamp
import java.time.Instant;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simulace JWT-style payloadu
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-bezpečné, bez paddingu)
Upozornění:Nevolejte toString() na byte[] s očekáváním jeho obsahu — výsledkem bude pouze hashovací identita pole jako [B@6d06d69c. Použijte new String(bytes, StandardCharsets.UTF_8) nebo předejte pole bajtů přímo metodě encodeToString().

Přehled metod Base64.Encoder

Třída java.util.Base64 nabízí tři tovární metody, každá vrací Base64.Encoder nakonfigurovaný pro konkrétní variantu. Instance kodérů jsou thread-safe a bezstavové — vytvořte je jednou a opakovaně je používejte.

Metoda
Typ
Popis
getEncoder()
Base64.Encoder
Vrací základní kodér dle RFC 4648 používající standardní abecedu (A-Z, a-z, 0-9, +, /)
getUrlEncoder()
Base64.Encoder
Vrací kodér s URL-bezpečnou abecedou (- místo +, _ místo /)
getMimeEncoder()
Base64.Encoder
Vrací MIME kodér vkládající zalomení řádků \r\n každých 76 znaků
getMimeEncoder(lineLength, lineSeparator)
Base64.Encoder
MIME kodér s vlastní délkou řádku a oddělovačem bajtů
encoder.withoutPadding()
Base64.Encoder
Vrací kodér vynechávající znaky = na konci (padding)
encoder.encode(byte[])
byte[]
Zakóduje pole bajtů, vrátí zakódované pole bajtů
encoder.encodeToString(byte[])
String
Zakóduje pole bajtů, vrátí přímo zakódovaný String
encoder.wrap(OutputStream)
OutputStream
Obalí OutputStream pro streamové kódování Base64

Base64.getUrlEncoder() — URL-bezpečné kódování

URL-bezpečný kodér používá alternativní abecedu, kde + se nahrazuje - a / se nahrazuje _, jak definuje RFC 4648 sekce 5. To je důležité kdykoli se Base64 řetězec vyskytuje v parametru URL dotazu, názvu souboru nebo hodnotě cookie — znaky standardního Base64 jsou v konfliktu s oddělovači URL a rezervovanými znaky souborového systému.

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);

// Standardní kodér — obsahuje + a / které narušují URL
String standard = Base64.getEncoder().encodeToString(data);
System.out.println(standard);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s/c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// URL-bezpečný kodér — bezpečný pro parametry dotazů a názvy souborů
String urlSafe = Base64.getUrlEncoder().encodeToString(data);
System.out.println(urlSafe);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// URL-bezpečný bez paddingu — pro JWT a kompaktní tokeny
String noPadding = Base64.getUrlEncoder().withoutPadding().encodeToString(data);
System.out.println(noPadding);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw

Varianta withoutPadding() odstraňuje znaky = na konci. Specifikace JWT vyžadují pro segmenty záhlaví a těla URL-bezpečné Base64 bez paddingu, takže getUrlEncoder().withoutPadding() je přesné volání, které potřebujete při ručním sestavování nebo manipulaci s JWT tokeny.

Poznámka:Metoda withoutPadding() vrací novou instanci kodéru — nemodifikuje původní. Obě lze přiřadit do polí static final a bezpečně sdílet mezi vlákny.

Kódování ze souboru a API odpovědi

Dva nejčastější reálné scénáře Base64 kódování v Javě: čtení binárního souboru z disku (certifikáty, obrázky, konfigurační balíčky) a kódování dat přijatých z HTTP odpovědi.

Zakódování souboru do Base64

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("Původní: %d bajtů%n", fileBytes.length);
            System.out.printf("Zakódováno: %d znaků%n", encoded.length());

            // Zápis zakódovaného obsahu do textového souboru
            Files.writeString(
                Path.of("certs/server.pem.b64"),
                encoded
            );
        } catch (java.io.IOException e) {
            System.err.println("Nepodařilo se načíst soubor: " + e.getMessage());
        }
    }
}

Zakódování těla API odpovědi

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("Zakódováno %d bajtů → %d znaků%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("Požadavek selhal: " + e.getMessage());
        }
    }
}

Krátká poznámka před sekcí o příkazové řádce: pokud potřebujete jen vložit soubor nebo API odpověď a získat Base64 výstup bez psaní kódu, zvládne to online Base64 Encoder pro textový i binární vstup.

Base64 kódování přes příkazovou řádku

Někdy potřebujete zakódovat řetězec nebo soubor přímo z terminálu — bez Java projektu, IDE ani sestavení. Většina Unix systémů obsahuje příkaz base64 a pokud máte nainstalovaný JDK, lze použít jshell pro Java-nativní přístup.

Bash — command-line Base64 encoding
# macOS / Linux — zakódování řetězce
echo -n "deploy-bot:sk_prod_9f2a7c4e" | base64
# ZGVwbG95LWJvdDpza19wcm9kXzlmMmE3YzRl

# Zakódování souboru
base64 < certs/server.pem > certs/server.pem.b64

# Pomocí jshell (JDK 9+)
echo 'System.out.println(java.util.Base64.getEncoder().encodeToString("deploy-bot:sk_prod_9f2a7c4e".getBytes()))' | jshell -

# Pomocí java přímo jako jednořádkový příkaz
java -e 'System.out.println(java.util.Base64.getEncoder().encodeToString(args[0].getBytes()))' "my-secret"
# Poznámka: java -e vyžaduje JDK 23+ (JEP 477)

Přístup přes jshell je obzvláště užitečný, když potřebujete ověřit, že váš Java kód produkuje stejný výstup jako Unix nástroj, nebo při ladění nesouladu mezi tím, co vaše služba odesílá, a tím, co příjemce očekává. Mám na to shell alias.

Poznámka:Na macOS příkaz base64 používá -D pro dekódování. Na Linuxu (GNU coreutils) používá -d. Chování kódování je na obou systémech identické. Příznak -w 0 na Linuxu zakáže zalomení řádků ve výstupu, což je obvykle žádoucí při přesměrování do dalších příkazů.

Apache Commons Codec — výkonná alternativa

Pro většinu aplikací je java.util.Base64 dostatečně rychlé. Pokud ale zpracováváte miliony kódovacích operací v těsné smyčce — například v pipeline pro příjem logů nebo ve vysoce výkonných message brokerech — stojí za to otestovat Apache Commons Codec. Existuje dlouho před Javou 8 a nabízí prověřenou alternativu s mírně odlišným 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);

// Standardní kódování
String encoded = Base64.encodeBase64String(telemetryPayload);

// URL-bezpečné kódování
String urlSafe = Base64.encodeBase64URLSafeString(telemetryPayload);

// Ověření, zda je řetězec platné Base64
boolean valid = Base64.isBase64(encoded);
System.out.println(valid);  // true

Apache Commons Codec také poskytuje Base64OutputStream a Base64InputStream pro streamové scénáře a validační metodu, kterou JDK kodér postrádá. Pokud je Commons Codec již ve vašem stromu závislostí (je součástí mnoha Apache projektů), není důvod jej nevyužít.

Guava BaseEncoding

Knihovna Guava od Googlu obsahuje BaseEncoding, která nabízí plynulé API pro Base64 s konfigurovatelným oddělovačem řádků, řízením paddingu a podporou standardní i URL-bezpečné abecedy. API je čtivé, ale přidávat Guavu (přibližně 3 MB) pouze kvůli Base64 kódování je zbytečné. Pokud je Guava ve vašem projektu již pro kolekce nebo cachovací utility, je kódovací API příjemným bonusem.

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);

// Standardní Base64
String standard = BaseEncoding.base64().encode(webhookPayload);

// URL-bezpečné
String urlSafe = BaseEncoding.base64Url().encode(webhookPayload);

// Bez paddingu
String noPad = BaseEncoding.base64Url().omitPadding().encode(webhookPayload);

// Se zalomením řádků (PEM styl)
String wrapped = BaseEncoding.base64()
    .withSeparator("\n", 64)
    .encode(webhookPayload);

Base64.getMimeEncoder() — MIME a PEM výstup se zalomením řádků

MIME kodér vkládá zalomení řádků \r\n každých 76 znaků, v souladu se specifikací MIME (RFC 2045). PEM certifikáty, S/MIME e-mailové přílohy a některá starší API tento formát vyžadují. Standardní a URL-bezpečné kodéry produkují jeden nepřerušený řádek — pokud jejich výstup předáte systému očekávajícímu Base64 se zalomením řádků, může tiše selhat nebo data odmítnout.

Java — MIME Base64 encoding
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simulace těla PEM certifikátu
byte[] certData = new byte[256];  // V praxi načtěte z .der souboru
new java.security.SecureRandom().nextBytes(certData);

// Výchozí MIME kodér — 76 znaků na řádek, oddělovač \r\n
String mimeEncoded = Base64.getMimeEncoder().encodeToString(certData);
System.out.println(mimeEncoded);
// QYx2K3p8Xg7JmN1R+wFkLd...  (76 znaků)
// Ht5Bv9CzAq0PnSjYl8WxUe...  (76 znaků)
// ...

// Vlastní MIME kodér — 64 znaků na řádek (standard PEM), oddělovač \n
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-----");
Upozornění:Nepoužívejte getMimeEncoder() pro JWT tokeny, HTTP hlavičky ani parametry URL. Zalomení řádků by data v těchto kontextech poškodilo. Místo toho použijte getEncoder() nebo getUrlEncoder().

Streamování velkých souborů pomocí Base64.getEncoder().wrap()

Načtení celého souboru do byte[] pomocí Files.readAllBytes() funguje pro malé soubory, ale u čehokoli nad 50–100 MB hrozí OutOfMemoryError. JDK nabízí Base64.getEncoder().wrap(OutputStream), který vrací OutputStream kódující data průběžně při zápisu. Zakódované bajty proudí do podkladového streamu bez bufferování celého vstupu.

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("Streamováno %d bajtů přes Base64 kodér%n", totalBytes);
        }
        // Uzavření base64Out automaticky zapíše poslední padding bajty
    }
}

Blok try-with-resources zajišťuje flush a uzavření. Jeden detail, na který lidé narazí: finální Base64 padding je zapsán až při uzavření obalujícího OutputStream. Pokud jej zapomenete zavřít (nebo zavřete pouze vnější stream), poslední znaky zakódovaného výstupu mohou chybět.

Streamování do síťového socketu

Metoda wrap() funguje s libovolným OutputStream — soubory, sockety, tělo HTTP odpovědi, dokonce i ByteArrayOutputStream. Zde je příklad zápisu Base64-zakódovaných dat přímo do paměťového bufferu, což je užitečné pro unit testy nebo sestavení payloadů k odeslání přes HTTP:

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)) {
    // Zápis dat po částech — simuluje čtení ze streamu
    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=

// Ověření zpětné konverze
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
Poznámka:Velikost bufferu v příkladu streamování (8192 bajtů) není náhodná. Odpovídá výchozí velikosti bufferu BufferedInputStream a je dobrou rovnováhou mezi spotřebou paměti a režií systémových volání. Menší buffery zvyšují počet read/write volání; větší buffery plýtvají pamětí bez znatelného zlepšení propustnosti.

Thread-safe instance kodérů — ukládejte a opakovaně používejte

Instance Base64.Encoder vrácená továrními metodami je neměnná a thread-safe. Volání Base64.getEncoder() při každé kódovací operaci vytváří pokaždé nový objekt. JVM to pravděpodobně optimalizuje, ale uložení kodéru do pole static final dává záměr jasně najevo a zabraňuje zbytečným alokacím ve výkonově kritických cestách.

Java — reusable encoder instances
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class TokenService {
    // Vytvoří se jednou, používá se všude — thread-safe
    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);
    }
}

Tento vzor je obzvláště užitečný ve Spring Boot službách, kde utility třída zajišťuje kódování napříč více controllery nebo servisními metodami. Volání withoutPadding() vrací novou instanci kodéru, takže můžete ukládat verze s paddingem i bez jako samostatná pole. Každé volání encodeToString() nebo encode() je bezstavové — žádná synchronizace není potřeba, žádný sdílený měnitelný stav.

Časté chyby

Volání getBytes() bez specifikace znakové sady

Problém: String.getBytes() bez argumentu znakové sady používá výchozí kódování platformy — windows-1252 na Windows, UTF-8 na většině Linuxových systémů a různě na macOS. Stejný kód produkuje různý Base64 výstup na různých strojích.

Řešení: Vždy explicitně předávejte StandardCharsets.UTF_8.

Before · Java
After · Java
String text = "Přístupový klíč: prod-east";
byte[] bytes = text.getBytes();  // výchozí platformní — nepředvídatelné
String encoded = Base64.getEncoder().encodeToString(bytes);
String text = "Přístupový klíč: prod-east";
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(bytes);
Použití standardního kodéru pro parametry URL

Problém: Base64.getEncoder() produkuje znaky + a /. Při vložení do URL query řetězce je + interpretován jako mezera a / jako oddělovač cesty, čímž se hodnota na straně příjemce tiše poškodí.

Řešení: Pro jakoukoliv hodnotu, která se vyskytne v URL, použijte Base64.getUrlEncoder().

Before · Java
After · Java
// Token v URL parametru — bude poškozeno
String token = Base64.getEncoder()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
// URL-bezpečné kódování — žádné znaky + ani /
String token = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
Dekódování pomocí nesprávné varianty kodéru

Problém: Kódování pomocí getUrlEncoder() a dekódování pomocí getDecoder() (nebo naopak) vyvolá IllegalArgumentException, protože - a _ nejsou platné znaky standardní Base64 abecedy a + a / nejsou platné v URL-bezpečné abecedě.

Řešení: Vždy dekódujte odpovídajícím dekodérem: getUrlDecoder() pro URL-bezpečné, getDecoder() pro standardní.

Before · Java
After · Java
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Později...
byte[] decoded = Base64.getDecoder()  // ŠPATNÝ dekodér
    .decode(encoded);
// IllegalArgumentException pokud encoded obsahuje - nebo _
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Později...
byte[] decoded = Base64.getUrlDecoder()  // odpovídající dekodér
    .decode(encoded);
Neuzavření wrap() OutputStream

Problém: Streamový kodér bufferuje až 2 vstupní bajty čekající na kompletní skupinu 3 bajtů. Pokud obalující OutputStream neuzavřete, poslední 1–4 Base64 znaky (včetně paddingu) nejsou nikdy zapsány.

Řešení: Použijte try-with-resources, nebo volejte close() explicitně na obalujícím streamu před čtením výstupu.

Before · Java
After · Java
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream b64os = Base64.getEncoder().wrap(baos);
b64os.write(data);
// baos.toString() je NEÚPLNÉ — chybí poslední bajty
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream b64os = Base64.getEncoder().wrap(baos)) {
    b64os.write(data);
}  // close() zapíše finální padding
String encoded = baos.toString();  // kompletní

Metody Base64 kódování — srovnání

Metoda
URL-bezpečné
Streaming
Zalomení řádků
Vlastní typy
Vyžaduje instalaci
Base64.getEncoder()
✓ (wrap)
Ne (JDK 8+)
Base64.getUrlEncoder()
✓ (wrap)
Ne (JDK 8+)
Base64.getMimeEncoder()
✓ (wrap)
✓ (76 znaků)
Ne (JDK 8+)
Apache Commons Codec
Maven závislost
Guava BaseEncoding
✓ (konfigurovatelné)
Maven závislost
jcmd / CLI base64
✓ (pipe)
N/A
Systémová instalace

Pro většinu projektů: java.util.Base64 je správná volba. Žádné závislosti, součást JDK, thread-safe a pokrývá všechny tři varianty RFC 4648. Sáhněte po Apache Commons Codec pouze pokud je již ve vašem classpath a potřebujete validační metodu isBase64() nebo streamující Base64OutputStream. Guavův BaseEncoding je rozumnou volbou, pokud váš projekt již na Guavě závisí, ale přidávat závislost o velikosti 3 MB jen kvůli Base64 je těžko obhajitelné.

Tři scénáře, tři volby: standardní webová služba potřebující Basic Auth nebo JWT kódování? Použijte JDK. Starší projekt již využívající Commons Codec přes Spring nebo Apache HTTP Client? Použijte jej — není důvod mít na classpath dvě Base64 knihovny. Projekt používající Guavu pro cachování a kolekce? Použijte BaseEncoding pro jeho čisté plynulé API. Nikdy nepřidávejte knihovnu jen kvůli Base64 kódování — JDK verze je dostatečně dobrá od roku 2014.

Pokud potřebujete rychle ověřit zakódovaný výsledek bez spouštění Java kódu, vložte jej do Base64 Encoderu a zkontrolujte, zda výstup odpovídá tomu, co váš kód produkuje.

Často kladené otázky

Jak zakóduji String v Javě do Base64?

Nejprve převeďte řetězec na bajty pomocí getBytes(StandardCharsets.UTF_8) a výsledné pole bajtů předejte metodě Base64.getEncoder().encodeToString(). Vždy explicitně zadávejte UTF-8 — volání getBytes() bez specifikace znakové sady používá výchozí nastavení platformy, které se liší mezi operačními systémy a konfiguracemi JVM.

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

Jaký je rozdíl mezi Base64.getEncoder() a Base64.getUrlEncoder()?

Obě metody kódují do Base64, ale getUrlEncoder() používá URL-bezpečnou abecedu definovanou v RFC 4648 sekci 5. Nahrazuje + za - a / za _, takže výstup lze vkládat do URL adres a názvů souborů bez percent-encodingu. Standardní kodér používá + a /, které jsou v konfliktu s parametry URL dotazů a segmenty cest.

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
// (stejné zde, ale + → - a / → _ při výskytu těchto znaků)

Je java.util.Base64 stejné v Javě 8 a Javě 17?

Ano. API java.util.Base64 se od svého zavedení v Javě 8 nezměnilo. Třída, její vnitřní třídy Encoder a Decoder a všechny tovární metody (getEncoder, getUrlEncoder, getMimeEncoder) jsou identické v Javě 8, 11, 17 i 21. Při aktualizaci verze JDK není potřeba žádná migrace ani změny kódu.

Java
// Tento kód se identicky kompiluje a spouští na Javě 8 až 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==

Jak zakóduji soubor do Base64 v Javě?

Načtěte soubor do pole bajtů pomocí Files.readAllBytes(Path) a předejte jej metodě Base64.getEncoder().encodeToString(). Pro velké soubory, které nechcete celé načítat do paměti, použijte Base64.getEncoder().wrap(OutputStream) pro streamové kódování výstupu.

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);

Proč byl sun.misc.BASE64Encoder označen jako zastaralý?

sun.misc.BASE64Encoder byla interní třída JDK, která nikdy nebyla součástí veřejného API. Nacházela se v balíčku sun.misc, jehož použití Oracle výslovně nedoporučoval. Java 8 zavedla java.util.Base64 jako oficiální, veřejnou a podporovanou náhradu. Od Javy 9 a modulárního systému přístup ke třídám sun.misc generuje varování nebo chyby v závislosti na konfiguraci JDK.

Java
// Starý způsob — NEPOUŽÍVEJTE, odstraněno v moderních JDK
// import sun.misc.BASE64Encoder;
// String encoded = new BASE64Encoder().encode(data);

// Správný způsob od Javy 8
import java.util.Base64;
String encoded = Base64.getEncoder().encodeToString(data);

Jak provést Base64 kódování a dekódování tam a zpět v Javě?

Zakódujte pomocí Base64.getEncoder().encodeToString(bytes) a dekódujte pomocí Base64.getDecoder().decode(encodedString). Dekódované pole bajtů převeďte zpět na String pomocí new String(bytes, StandardCharsets.UTF_8). Zpětná konverze zachová původní data přesně — pokud použijete stejnou znakovou sadu pro getBytes() i new String().

Java
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Kódování
String original = "session_token=eyJhbGciOiJSUzI1NiJ9";
byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(originalBytes);

// Dekódování
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);

System.out.println(original.equals(decoded));  // true

Související nástroje

  • Base64 DecoderDekóduje Base64 řetězce zpět do původní textové nebo binární podoby — opačná operace ke kódování.
  • URL EncoderPercent-enkóduje řetězce pro bezpečné použití v URL adresách — liší se od URL-bezpečného Base64 kódování, ale často se používají společně.
  • JWT DecoderProhlíží JWT tokeny, jejichž záhlaví a tělo jsou zakódovány jako Base64url JSON — dekódování bez knihovny.
  • JSON FormatterFormátuje JSON payloady před Base64 kódováním nebo po něm — užitečné při ladění API integrací.
Dostupné také v: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 NovakTechnický recenzent

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.