Codifica Base64 in Java — Esempi java.util.Base64
Usa il Codificatore Base64 Online gratuito direttamente nel tuo browser — nessuna installazione.
Prova Codificatore Base64 Online online →Ogni volta che configuro un header HTTP Basic Auth, incorporo un certificato in un secret Kubernetes o trasmetto dati binari attraverso un'API JSON, il primo passo è sempre lo stesso: codificare in Base64 i byte grezzi in una stringa sicura per ASCII. Java semplifica tutto questo con java.util.Base64, l'API standard disponibile da Java 8 che ha sostituito il deprecato sun.misc.BASE64Encoder. Per una codifica rapida al volo senza scrivere codice, il Base64 Encoder di ToolDeck la gestisce istantaneamente nel browser. Questa guida copre Base64.getEncoder(), getUrlEncoder(), getMimeEncoder(), la codifica di file, lo streaming con wrap(OutputStream), e gli errori che mettono in difficoltà anche gli sviluppatori Java esperti. Tutti gli esempi compilano su Java 8 fino a Java 21+.
- ✓Base64.getEncoder().encodeToString(bytes) è il one-liner standard — integrato nel JDK da Java 8, invariato in Java 17 e 21.
- ✓Passa sempre StandardCharsets.UTF_8 a String.getBytes() prima della codifica — ometterlo usa il default della piattaforma, che varia tra le JVM.
- ✓getUrlEncoder() produce output URL-safe (- al posto di +, _ al posto di /) e withoutPadding() rimuove i caratteri = finali.
- ✓getMimeEncoder() inserisce interruzioni di riga ogni 76 caratteri — richiesto dai formati email (MIME) e dai certificati PEM.
- ✓Per file di grandi dimensioni, usa Base64.getEncoder().wrap(OutputStream) per lo streaming senza caricare l'intero file in memoria.
Cos'è la codifica Base64?
Base64 converte dati binari arbitrari in una stringa composta da 64 caratteri ASCII stampabili: A-Z, a-z, 0-9, + e /. Ogni 3 byte di input producono esattamente 4 caratteri Base64. Se la lunghezza dell'input non è un multiplo di 3, vengono aggiunti uno o due caratteri di padding =. L'output codificato è sempre circa il 33% più grande dei dati originali.
Base64 non è cifratura. Chiunque abbia la stringa codificata può decodificarla. Il suo scopo è la sicurezza del trasporto: gli header HTTP, i payload JSON, i documenti XML e il corpo delle email sono protocolli basati su testo che non possono trasportare byte binari grezzi senza corruzione. I casi d'uso comuni in Java includono l'autenticazione HTTP Basic, l'incorporamento di certificati PEM, la memorizzazione di dati binari in colonne di testo dei database e la costruzione di segmenti di token JWT.
deploy-svc:sk_live_4eC39HqLyjWDarjtT1zdp7dc
ZGVwbG95LXN2Yzpza19saXZlXzRlQzM5SHFMeWpXRGFyanRUMXpkcDdkYw==
Base64.getEncoder().encodeToString() — L'API standard
java.util.Base64 è stata introdotta in Java 8 come sostituto ufficiale di sun.misc.BASE64Encoder. La classe fornisce tre factory method statici — ognuno restituisce un'istanza della classe Base64.Encoder annidata — che coprono le tre varianti Base64 definite nell'RFC 4648. Non occorre nessuna libreria di terze parti. Nessuna dipendenza Maven. Basta importare e chiamare.
Esempio minimale — Codifica una String
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
}
}Il passaggio chiave che molti sviluppatori Java mancano al primo tentativo: una String deve essere convertita in byte[] prima della codifica. Base64 opera sui byte, non sui caratteri. encodeToString() accetta un byte[] e restituisce direttamente la String Base64. Se hai bisogno del risultato codificato come byte invece, usa encode(byte[]) — restituisce un byte[] dei caratteri Base64 codificati in ASCII, utile quando scrivi direttamente su un OutputStream o costruisci frame di protocollo binario.
HTTP Basic Auth — Il caso d'uso più comune
L'autenticazione HTTP Basic è probabilmente il motivo più comune per cui gli sviluppatori Java ricorrono alla codifica Base64. La specifica (RFC 7617) richiede che la stringa di credenziali username:password sia codificata in Base64 e inserita nell'header Authorization. Ho visto questo fatto in modo errato più volte di quanto possa contare — di solito dimenticando il separatore due punti o codificando i componenti separatamente.
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
}
}Round-Trip — Codifica e decodifica
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";
// Codifica
String encoded = Base64.getEncoder()
.encodeToString(original.getBytes(StandardCharsets.UTF_8));
System.out.println(encoded);
// WC1Db3JyZWxhdGlvbi1JRDogcmVxXzhhNGYyYzkxLWU3YjMtNGQ1Ni05MDEyLTNmN2E4YjljMGQxZQ==
// Decodifica
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println(original.equals(decoded)); // true
}
}java.util.Base64 è identica da Java 8 a Java 17 e Java 21. Non è necessaria alcuna migrazione quando si aggiorna il JDK. Lo stesso codice compila ed esegue su qualsiasi versione da Java 8 in poi.Codifica di dati non String — byte[], UUID e Timestamp
La codifica Base64 in Java inizia sempre con un byte[]. Le stringhe si convertono tramite getBytes(StandardCharsets.UTF_8), ma gli altri tipi richiedono prima un passaggio di conversione. UUID, timestamp e identificatori numerici devono essere serializzati in una stringa o in una rappresentazione byte prima di poterli codificare in Base64.
UUID — Codifica come rappresentazione String
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);
// NmJhN2I4MTAtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4UUID compatto — Codifica i 16 byte grezzi
Se vuoi un risultato codificato più breve, estrai i 128 bit dell'UUID come 16 byte grezzi invece di convertirli nella forma stringa a 36 caratteri. L'output Base64 scende da 48 caratteri a 24.
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 caratteri contro 48 dell'approccio basato su stringaTimestamp e payload misto
import java.time.Instant;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
// Simulazione di un payload in stile JWT
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-safe, senza padding)toString() su un byte[] aspettandoti il suo contenuto — otterrai l'hash dell'identità dell'array come [B@6d06d69c. Usa new String(bytes, StandardCharsets.UTF_8) o passa l'array di byte direttamente a encodeToString().Riferimento ai metodi di Base64.Encoder
La classe java.util.Base64 espone tre factory method, ognuno restituisce un Base64.Encoder configurato per una variante specifica. Le istanze dell'encoder sono thread-safe e stateless — creale una volta e riutilizzale.
Base64.getUrlEncoder() — Codifica URL-Safe
L'encoder URL-safe usa un alfabeto alternativo dove + diventa - e / diventa _, come definito nella Sezione 5 dell'RFC 4648. Questo è importante ogni volta che la stringa Base64 compare in un parametro di query URL, un nome di file o un valore di cookie — i caratteri Base64 standard entrano in conflitto con i delimitatori URL e i caratteri riservati del filesystem.
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); // Encoder standard — contiene + e / che rompono gli URL String standard = Base64.getEncoder().encodeToString(data); System.out.println(standard); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s/c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw== // Encoder URL-safe — sicuro per parametri di query e nomi di file String urlSafe = Base64.getUrlEncoder().encodeToString(data); System.out.println(urlSafe); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw== // URL-safe senza padding — per JWT e token compatti String noPadding = Base64.getUrlEncoder().withoutPadding().encodeToString(data); System.out.println(noPadding); // aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw
La variante withoutPadding() rimuove i caratteri = finali. Le specifiche JWT richiedono Base64 URL-safe senza padding per i segmenti header e payload, quindi getUrlEncoder().withoutPadding() è esattamente la chiamata che ti serve quando costruisci o manipoli token JWT manualmente.
withoutPadding() restituisce una nuova istanza encoder — non modifica l'originale. Entrambe possono essere assegnate a campi static final e riutilizzate in sicurezza tra i thread.Codifica da file e risposta API
I due scenari reali più comuni per la codifica Base64 in Java: leggere un file binario dal disco (certificati, immagini, bundle di configurazione) e codificare dati ricevuti da una risposta HTTP.
Codifica un file in Base64
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("Originale: %d byte%n", fileBytes.length);
System.out.printf("Codificato: %d caratteri%n", encoded.length());
// Scrivi il contenuto codificato in un file di testo
Files.writeString(
Path.of("certs/server.pem.b64"),
encoded
);
} catch (java.io.IOException e) {
System.err.println("Impossibile leggere il file: " + e.getMessage());
}
}
}Codifica il corpo di una risposta API
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("Codificati %d byte → %d caratteri%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("Richiesta fallita: " + e.getMessage());
}
}
}Una nota rapida prima della sezione CLI: se hai solo bisogno di incollare un file o una risposta API e ottenere l'output Base64 senza scrivere codice, il Base64 Encoder online gestisce sia input di testo che binari.
Codifica Base64 da riga di comando
A volte hai solo bisogno di codificare una stringa o un file dal terminale — senza progetto Java, senza IDE, senza passaggio di build. La maggior parte dei sistemi Unix include il comando base64, e se hai un JDK installato, puoi usare jshell per un approccio nativo Java.
# macOS / Linux — codifica una stringa
echo -n "deploy-bot:sk_prod_9f2a7c4e" | base64
# ZGVwbG95LWJvdDpza19wcm9kXzlmMmE3YzRl
# Codifica un file
base64 < certs/server.pem > certs/server.pem.b64
# Usando jshell (JDK 9+)
echo 'System.out.println(java.util.Base64.getEncoder().encodeToString("deploy-bot:sk_prod_9f2a7c4e".getBytes()))' | jshell -
# Usando java direttamente con un one-liner
java -e 'System.out.println(java.util.Base64.getEncoder().encodeToString(args[0].getBytes()))' "my-secret"
# Nota: java -e richiede JDK 23+ (JEP 477)L'approccio con jshell è particolarmente utile quando devi verificare che il tuo codice Java produca lo stesso output di uno strumento Unix, o quando stai eseguendo il debug di una discrepanza tra ciò che il tuo servizio invia e ciò che il ricevente si aspetta. Ho un alias shell per questo.
base64 usa -D per decodificare. Su Linux (GNU coreutils) usa -d. Il comportamento di codifica è identico su entrambi. Il flag -w 0 su Linux disabilita il ritorno a capo nell'output, che di solito è quello che vuoi quando passi il risultato ad altri comandi.Apache Commons Codec — Alternativa ad alte prestazioni
Per la maggior parte delle applicazioni, java.util.Base64 è sufficientemente veloce. Ma se stai elaborando milioni di operazioni di codifica in un loop stretto — come pipeline di ingestione log o message broker ad alta produttività — Apache Commons Codec vale la pena di essere testato. Esiste da prima di Java 8 e offre un'alternativa collaudata con un'API leggermente diversa.
// 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);
// Codifica standard
String encoded = Base64.encodeBase64String(telemetryPayload);
// Codifica URL-safe
String urlSafe = Base64.encodeBase64URLSafeString(telemetryPayload);
// Verifica se una stringa è Base64 valida
boolean valid = Base64.isBase64(encoded);
System.out.println(valid); // trueApache Commons Codec fornisce anche Base64OutputStream e Base64InputStream per scenari di streaming, e include un metodo di validazione che all'encoder JDK manca. Se Commons Codec è già nel tuo albero delle dipendenze (è incluso in molti progetti Apache), non c'è motivo di non usarlo.
Guava BaseEncoding
La libreria Guava di Google include BaseEncoding, che offre un'API fluent per Base64 con separatori di riga configurabili, controllo del padding e supporto per entrambi gli alfabeti standard e URL-safe. L'API è leggibile, ma aggiungere Guava (circa 3 MB) solo per la codifica Base64 è eccessivo. Se Guava è già nel tuo progetto per le sue utilità di collezioni o caching, l'API di codifica è un bonus gradito.
// 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);
// Base64 standard
String standard = BaseEncoding.base64().encode(webhookPayload);
// URL-safe
String urlSafe = BaseEncoding.base64Url().encode(webhookPayload);
// Senza padding
String noPad = BaseEncoding.base64Url().omitPadding().encode(webhookPayload);
// Con separatori di riga (stile PEM)
String wrapped = BaseEncoding.base64()
.withSeparator("\n", 64)
.encode(webhookPayload);Base64.getMimeEncoder() — Output con a capo per MIME e PEM
L'encoder MIME inserisce interruzioni di riga \r\n ogni 76 caratteri, rispettando la specifica MIME (RFC 2045). I certificati PEM, gli allegati email S/MIME e alcune API legacy si aspettano questo formato. Gli encoder standard e URL-safe producono una singola riga ininterrotta — se passi il loro output a un sistema che si aspetta Base64 con a capo, potrebbe fallire silenziosamente o rifiutare i dati.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
// Simulazione del corpo di un certificato PEM
byte[] certData = new byte[256]; // In pratica, leggi da un file .der
new java.security.SecureRandom().nextBytes(certData);
// Encoder MIME predefinito — 76 caratteri per riga, separatore \r\n
String mimeEncoded = Base64.getMimeEncoder().encodeToString(certData);
System.out.println(mimeEncoded);
// QYx2K3p8Xg7JmN1R+wFkLd... (76 caratteri)
// Ht5Bv9CzAq0PnSjYl8WxUe... (76 caratteri)
// ...
// Encoder MIME personalizzato — 64 caratteri per riga (standard PEM), separatore \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-----");getMimeEncoder() per token JWT, header HTTP o parametri URL. I ritorni a capo corromperanno i dati in questi contesti. Usa getEncoder() o getUrlEncoder() invece.Streaming di file grandi con Base64.getEncoder().wrap()
Caricare un intero file in un byte[] con Files.readAllBytes() funziona per file piccoli, ma per qualsiasi file oltre 50-100 MB rischi un OutOfMemoryError. Il JDK fornisce Base64.getEncoder().wrap(OutputStream), che restituisce un OutputStream che codifica i dati al volo mentre li scrivi. I byte codificati fluiscono verso lo stream sottostante senza bufferizzare l'intero input.
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("Trasmessi in streaming %d byte attraverso l'encoder Base64%n", totalBytes);
}
// La chiusura di base64Out scrive automaticamente i byte di padding finali
}
}Il blocco try-with-resources gestisce il flush e la chiusura. Un dettaglio che coglie molti di sorpresa: il padding Base64 finale viene scritto solo quando il OutputStream avvolgente viene chiuso. Se dimentichi di chiuderlo (o chiudi solo lo stream esterno), gli ultimi caratteri dell'output codificato potrebbero mancare.
Streaming verso un socket di rete
Il metodo wrap() funziona con qualsiasi OutputStream — output di file, output di socket, corpo di risposta HTTP, persino ByteArrayOutputStream. Ecco un esempio che scrive dati codificati in Base64 direttamente in un buffer in memoria, utile per i test unitari o per costruire payload da inviare via HTTP:
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)) {
// Scrivi i dati in chunk — simula la lettura da uno 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=
// Verifica del round-trip
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 ed è un buon equilibrio tra utilizzo della memoria e overhead delle system call. Buffer più piccoli aumentano il numero di chiamate read/write; buffer più grandi sprecano memoria senza un miglioramento significativo della produttività.Istanze encoder thread-safe — Memorizza e riutilizza
Il Base64.Encoder restituito dai factory method è immutabile e thread-safe. Chiamare Base64.getEncoder() ad ogni operazione di codifica crea un nuovo oggetto ogni volta. La JVM probabilmente ottimizzerà questo, ma memorizzare l'encoder in un campo static final rende l'intenzione chiara ed evita allocazioni inutili nei percorsi critici.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class TokenService {
// Crea una volta, riutilizza ovunque — 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);
}
}Questo pattern è particolarmente utile nei servizi Spring Boot dove una classe di utilità gestisce la codifica in più controller o metodi di servizio. La chiamata a withoutPadding() restituisce una nuova istanza encoder, quindi puoi memorizzare le varianti con e senza padding come campi separati. Ogni chiamata a encodeToString() o encode() è stateless — nessuna sincronizzazione necessaria, nessuno stato mutabile condiviso.
Errori comuni
Problema: String.getBytes() senza argomento charset usa la codifica predefinita della piattaforma, che è windows-1252 su Windows, UTF-8 sulla maggior parte dei sistemi Linux e varia su macOS. Lo stesso codice produce output Base64 diversi su macchine diverse.
Soluzione: Passa sempre StandardCharsets.UTF_8 esplicitamente.
String text = "Ключ доступа: prod-east"; byte[] bytes = text.getBytes(); // default di piattaforma — imprevedibile String encoded = Base64.getEncoder().encodeToString(bytes);
String text = "Ключ доступа: prod-east"; byte[] bytes = text.getBytes(StandardCharsets.UTF_8); String encoded = Base64.getEncoder().encodeToString(bytes);
Problema: Base64.getEncoder() produce caratteri + e /. Quando inseriti in una query string URL, + viene interpretato come spazio e / come separatore di percorso, corrompendo silenziosamente il valore sul lato ricevente.
Soluzione: Usa Base64.getUrlEncoder() per qualsiasi valore che comparirà in un URL.
// Token nel parametro di query URL — si romperà
String token = Base64.getEncoder()
.encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;// Codifica URL-safe — nessun carattere + o /
String token = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;Problema: Codificare con getUrlEncoder() e decodificare con getDecoder() (o viceversa) lancia IllegalArgumentException perché - e _ non sono validi nell'alfabeto Base64 standard, e + e / non sono validi nell'alfabeto URL-safe.
Soluzione: Decodifica sempre con il decoder corrispondente: getUrlDecoder() per URL-safe, getDecoder() per standard.
String encoded = Base64.getUrlEncoder()
.encodeToString(data);
// Dopo...
byte[] decoded = Base64.getDecoder() // decoder SBAGLIATO
.decode(encoded);
// IllegalArgumentException se encoded contiene - o _String encoded = Base64.getUrlEncoder()
.encodeToString(data);
// Dopo...
byte[] decoded = Base64.getUrlDecoder() // decoder corrispondente
.decode(encoded);Problema: L'encoder in streaming bufferizza fino a 2 byte di input in attesa di un gruppo completo di 3 byte. Se non chiudi l'OutputStream avvolgente, gli ultimi 1-4 caratteri Base64 (incluso il padding) non vengono mai scritti.
Soluzione: Usa try-with-resources o chiama close() esplicitamente sullo stream avvolto prima di leggere l'output.
ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream b64os = Base64.getEncoder().wrap(baos); b64os.write(data); // baos.toString() è INCOMPLETO — mancano i byte finali
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream b64os = Base64.getEncoder().wrap(baos)) {
b64os.write(data);
} // close() scrive il padding finale
String encoded = baos.toString(); // completoMetodi di codifica Base64 — Confronto
Per la maggior parte dei progetti: java.util.Base64 è la scelta giusta. Zero dipendenze, integrato nel JDK, thread-safe e copre tutte e tre le varianti RFC 4648. Ricorri ad Apache Commons Codec solo se è già nel tuo classpath e hai bisogno del metodo di validazione isBase64() o del Base64OutputStream in streaming. BaseEncoding di Guava è un'opzione ragionevole se il tuo progetto dipende già da Guava, ma aggiungere una dipendenza da 3 MB solo per Base64 è difficile da giustificare.
Tre scenari, tre scelte: servizio web standard che necessita di codifica per Basic Auth o JWT? Resta con il JDK. Progetto legacy che include già Commons Codec tramite Spring o Apache HTTP Client? Usalo — nessuna ragione di avere due librerie Base64 nel classpath. Progetto che usa Guava per caching e collezioni? Usa BaseEncoding per la sua API fluent pulita. Non aggiungere mai una libreria solo per la codifica Base64 — la versione JDK è più che sufficiente dal 2014.
Se hai bisogno di verificare rapidamente un risultato codificato senza eseguire il tuo codice Java, incollalo nel Base64 Encoder per confermare che l'output corrisponda a quello prodotto dal tuo codice.
Domande frequenti
Come si codifica una String in Base64 in Java?
Converti prima la stringa in byte usando getBytes(StandardCharsets.UTF_8), poi passa l'array di byte a Base64.getEncoder().encodeToString(). Specifica sempre UTF-8 esplicitamente — chiamare getBytes() senza argomento charset usa il default della piattaforma, che varia tra sistemi operativi e configurazioni JVM.
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));
// Z3JhbnRfdHlwZT1jbGllbnRfY3JlZGVudGlhbHMmc2NvcGU9cmVhZDptZXRyaWNzQual è la differenza tra Base64.getEncoder() e Base64.getUrlEncoder()?
Entrambi codificano in Base64, ma getUrlEncoder() usa l'alfabeto URL-safe definito nella Sezione 5 dell'RFC 4648. Sostituisce + con - e / con _ in modo che l'output possa comparire in URL e nomi di file senza percent-encoding. L'encoder standard usa + e / che entrano in conflitto con i parametri di query e i segmenti di percorso degli URL.
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 // (uguale qui, ma con + → - e / → _ quando compaiono)
java.util.Base64 è uguale in Java 8 e Java 17?
Sì. L'API java.util.Base64 non è cambiata da quando è stata introdotta in Java 8. La classe, le classi annidate Encoder e Decoder e tutti i factory method (getEncoder, getUrlEncoder, getMimeEncoder) sono identici in Java 8, 11, 17 e 21. Non sono necessarie migrazioni o modifiche al codice quando si aggiorna la versione del JDK.
// Questo codice compila ed esegue identicamente da Java 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==Come si codifica un file in Base64 in Java?
Leggi il file in un array di byte con Files.readAllBytes(Path) e passalo a Base64.getEncoder().encodeToString(). Per file di grandi dimensioni che non devono essere caricati interamente in memoria, usa Base64.getEncoder().wrap(OutputStream) per trasmettere in streaming l'output codificato.
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);Perché sun.misc.BASE64Encoder è stato deprecato?
sun.misc.BASE64Encoder era una classe interna del JDK che non ha mai fatto parte dell'API pubblica. Si trovava nel package sun.misc, che Oracle ha sempre sconsigliato esplicitamente di usare. Java 8 ha introdotto java.util.Base64 come sostituto ufficiale, pubblico e supportato. Da Java 9 con il sistema di moduli, l'accesso alle classi sun.misc produce avvisi o errori a seconda della configurazione del JDK.
// Vecchio modo — NON usare, rimosso nei JDK moderni // import sun.misc.BASE64Encoder; // String encoded = new BASE64Encoder().encode(data); // Modo corretto da Java 8 import java.util.Base64; String encoded = Base64.getEncoder().encodeToString(data);
Come si esegue un round-trip Base64 encode e decode in Java?
Codifica con Base64.getEncoder().encodeToString(bytes) e decodifica con Base64.getDecoder().decode(encodedString). Converti l'array di byte decodificato in String usando new String(bytes, StandardCharsets.UTF_8). Il round-trip preserva i dati originali esattamente — a patto di usare lo stesso charset sia per getBytes() che per new String().
import java.util.Base64; import java.nio.charset.StandardCharsets; // Codifica String original = "session_token=eyJhbGciOiJSUzI1NiJ9"; byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8); String encoded = Base64.getEncoder().encodeToString(originalBytes); // Decodifica byte[] decodedBytes = Base64.getDecoder().decode(encoded); String decoded = new String(decodedBytes, StandardCharsets.UTF_8); System.out.println(original.equals(decoded)); // true
Strumenti correlati
- Base64 Decoder — Decodifica stringhe Base64 nella loro forma originale testuale o binaria — l'operazione inversa della codifica.
- URL Encoder — Codifica le stringhe con percent-encoding per un uso sicuro negli URL — diverso dalla codifica Base64 URL-safe, ma spesso usato insieme.
- JWT Decoder — Ispeziona i token JWT i cui segmenti header e payload sono JSON codificato in Base64url — decodificali senza librerie.
- JSON Formatter — Formatta i payload JSON prima o dopo la codifica Base64 — utile per il debug delle integrazioni API.
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.