Decodificação Base64 em Java é algo que uso quase todo dia — extraindo segredos de variáveis de ambiente do Kubernetes, lendo payloads binários de APIs REST, inspecionando tokens JWT durante uma sessão de depuração. A classe java.util.Base64 nativa do Java (desde o JDK 8) oferece três variantes de decodificador: getDecoder() para Base64 padrão, getUrlDecoder() para entradas URL-safe e getMimeDecoder() para dados com quebras de linha como anexos de e-mail. Para uma verificação rápida sem escrever código, o decodificador Base64 do ToolDeck resolve instantaneamente no navegador. Este guia é voltado para Java 8+ e cobre os três decodificadores, streaming com wrap(InputStream), extração de payload JWT, decodificação de arquivos e respostas de API, Apache Commons Codec como alternativa e os quatro erros que geram saída corrompida em produção.
- ✓Base64.getDecoder().decode(s) é a abordagem padrão — integrada ao java.util.Base64 desde o JDK 8, sem dependências externas.
- ✓Use getUrlDecoder() para tokens JWT e payloads OAuth — eles usam o alfabeto - e _, não + e /.
- ✓getMimeDecoder() ignora quebras de linha e espaços em branco, sendo a escolha certa para anexos de e-mail e certificados PEM.
- ✓decoder.wrap(InputStream) decodifica sob demanda para arquivos grandes sem carregar tudo na memória.
- ✓O decodificador básico é rigoroso — quebras de linha no final, espaços ou caracteres do alfabeto errado lançam IllegalArgumentException imediatamente.
O que é Decodificação Base64?
A codificação Base64 converte dados binários em uma representação ASCII de 64 caracteres para que possam trafegar com segurança por canais somente-texto — campos JSON, cabeçalhos HTTP, documentos XML, corpos de e-mail. A decodificação faz o inverso: cada 4 caracteres Base64 são mapeados de volta para 3 bytes originais. O padding = no final indica quantos bytes foram adicionados para completar o último grupo. Base64 não é criptografia — qualquer pessoa pode revertê-lo. Seu propósito é a segurança no transporte, não o sigilo.
Cenários típicos de decodificação em Java: extrair valores de configuração injetados como variáveis de ambiente Base64, desempacotar conteúdo de arquivo binário de respostas de APIs cloud, ler certificados codificados em PEM e inspecionar payloads de tokens JWT durante depuração.
ZGItcHJvZC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbTo1NDMy
db-prod.us-east-1.amazonaws.com:5432
Base64.getDecoder().decode() — O Método Padrão de Decodificação
A classe java.util.Base64 foi adicionada no JDK 8 e substituiu o antigo sun.misc.BASE64Decoder que todos usavam antes. Sem dependências externas necessárias — basta import java.util.Base64 e chamar Base64.getDecoder().decode(). O método aceita tanto uma String quanto um byte[] e retorna um byte[] com os dados decodificados.
Exemplo mínimo funcional
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class DecodeCredential {
public static void main(String[] args) {
// Valor de secret do Kubernetes, codificado em Base64
String encoded = "ZGItcHJvZC51cy1lYXN0LTEuYW1hem9uYXdzLmNvbTo1NDMy";
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String connectionString = new String(decodedBytes, StandardCharsets.UTF_8);
System.out.println(connectionString);
// db-prod.us-east-1.amazonaws.com:5432
}
}Sempre especifique StandardCharsets.UTF_8 ao construir a String. O construtor new String(bytes) sem argumentos usa a codificação padrão da plataforma, que varia entre sistemas. Em um servidor Windows com Cp1252 como padrão, caracteres UTF-8 multibyte são corrompidos silenciosamente.
Verificação de ida e volta
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class RoundTrip {
public static void main(String[] args) {
String original = "redis://cache-prod.internal:6379/session-store";
String encoded = Base64.getEncoder().encodeToString(
original.getBytes(StandardCharsets.UTF_8)
);
System.out.println(encoded);
// cmVkaXM6Ly9jYWNoZS1wcm9kLmludGVybmFsOjYzNzkvc2Vzc2lvbi1zdG9yZQ==
byte[] decoded = Base64.getDecoder().decode(encoded);
String recovered = new String(decoded, StandardCharsets.UTF_8);
System.out.println(recovered.equals(original)); // true
}
}Decodificação em um buffer pré-alocado
A sobrecarga de três argumentos decode(byte[] src, byte[] dst) escreve diretamente em um buffer de destino e retorna o número de bytes escritos. Isso evita uma alocação extra em caminhos críticos de desempenho:
import java.util.Base64;
public class DecodeToBuffer {
public static void main(String[] args) {
byte[] src = "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=".getBytes();
byte[] dst = new byte[1024]; // pré-alocado
int len = Base64.getDecoder().decode(src, dst);
String result = new String(dst, 0, len);
System.out.println(result);
// {"host":"10.0.1.50","port":8443}
}
}decode() lança IllegalArgumentException se a entrada contiver caracteres fora do alfabeto Base64 (incluindo quebras de linha e espaços). Se sua entrada puder ter espaços em branco, mude para getMimeDecoder() ou remova-os com encoded.strip() antes de decodificar.Decodificando Base64 com Tipos Não Padrão e Objetos Personalizados
O byte[] bruto retornado por decode() muitas vezes precisa se tornar algo mais específico: um UUID, um objeto Java serializado, uma mensagem protobuf ou um timestamp. O decodificador sempre retorna bytes — a conversão para tipos de domínio é de sua responsabilidade.
Base64 para UUID
import java.util.Base64;
import java.nio.ByteBuffer;
import java.util.UUID;
public class DecodeUUID {
public static UUID fromBase64(String encoded) {
byte[] bytes = Base64.getUrlDecoder().decode(encoded);
ByteBuffer bb = ByteBuffer.wrap(bytes);
return new UUID(bb.getLong(), bb.getLong());
}
public static void main(String[] args) {
// UUID compacto codificado em Base64 de uma resposta de API
String encoded = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
UUID original = UUID.fromString(encoded);
// Codificar em Base64 (forma compacta — 22 chars vs 36)
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(original.getMostSignificantBits());
bb.putLong(original.getLeastSignificantBits());
String compact = Base64.getUrlEncoder().withoutPadding()
.encodeToString(bb.array());
System.out.println(compact); // 9HrBC1jMQ3KlZw4CssPUeQ
// Decodificar de volta
UUID recovered = fromBase64(compact);
System.out.println(recovered); // f47ac10b-58cc-4372-a567-0e02b2c3d479
}
}Base64 para objeto JSON desserializado com Jackson
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;
public class DecodeJsonPayload {
record DeployEvent(String service, String region, Instant deployedAt, int replicas) {}
public static void main(String[] args) throws Exception {
// Payload JSON codificado em Base64 de uma fila de mensagens
String encoded = "eyJzZXJ2aWNlIjoicGF5bWVudC1nYXRld2F5Iiwi"
+ "cmVnaW9uIjoiZXUtd2VzdC0xIiwiZGVwbG95ZWRBdCI6"
+ "IjIwMjYtMDMtMTVUMTQ6MzA6MDBaIiwicmVwbGljYXMiOjR9";
byte[] jsonBytes = Base64.getDecoder().decode(encoded);
String json = new String(jsonBytes, StandardCharsets.UTF_8);
System.out.println(json);
// {"service":"payment-gateway","region":"eu-west-1",
// "deployedAt":"2026-03-15T14:30:00Z","replicas":4}
ObjectMapper mapper = new ObjectMapper();
mapper.findAndRegisterModules(); // picks up JavaTimeModule
DeployEvent event = mapper.readValue(jsonBytes, DeployEvent.class);
System.out.println(event.service()); // payment-gateway
System.out.println(event.deployedAt()); // 2026-03-15T14:30:00Z
}
}ObjectInputStream para desserializar dados Base64 não confiáveis. Ataques de desserialização do Java são bem documentados — se o conteúdo codificado vier de uma fonte externa, analise-o como JSON ou protobuf em vez de usar a serialização nativa do Java.Referência dos Métodos de Base64.Decoder
Todos os métodos pertencem a java.util.Base64 e sua classe interna Base64.Decoder. Os três métodos de fábrica em Base64 retornam instâncias de decodificador diferentes; os métodos decode() e wrap() vivem na instância Decoder.
getMimeDecoder() — Decodificando Base64 MIME com Quebras de Linha
O decodificador básico rejeita qualquer coisa fora do alfabeto Base64 — e isso inclui as quebras de linha \r\n que o conteúdo codificado em MIME sempre contém. Anexos de e-mail, certificados PEM e algumas respostas de API mais antigas quebram a saída Base64 em 76 caracteres por linha. getMimeDecoder() ignora silenciosamente separadores de linha e qualquer caractere que não esteja no alfabeto Base64, tratando isso automaticamente.
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class MimeDecode {
public static void main(String[] args) {
// Corpo de certificado PEM — quebrado a cada 76 caracteres
String pemBody = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t\r\n"
+ "TUlJQm96Q0NBVWlnQXdJQkFnSUpBSXBhVDJU\r\n"
+ "aVFvZU1BMEdDU3FHU0liM0RRRU==";
// getDecoder() lançaria IllegalArgumentException aqui
byte[] decoded = Base64.getMimeDecoder().decode(pemBody);
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// -----BEGIN CERTIFICATE-----
// MIIBozCCAUigAwIBAgIJAIpaT2T...
}
}getMimeDecoder() é permissivo: ignora caracteres inválidos em vez de lançar uma exceção. Isso é adequado para dados MIME conhecidos, mas pode engolir silenciosamente corrupção em entradas arbitrárias. Use getDecoder()quando quiser validação rigorosa.Decodificar Base64 de um Arquivo e Resposta de API
Lendo um arquivo codificado em Base64 do disco
Arquivos binários (imagens, certificados, blobs criptografados) às vezes são armazenados no disco como texto Base64. Leia o arquivo, decodifique e escreva a saída binária:
import java.util.Base64;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class DecodeFile {
public static void main(String[] args) {
Path inputPath = Path.of("tls-cert.pem.b64");
Path outputPath = Path.of("tls-cert.pem");
try {
String encoded = Files.readString(inputPath).strip();
byte[] decoded = Base64.getMimeDecoder().decode(encoded);
Files.write(outputPath, decoded);
System.out.printf("Decoded %d bytes → %s%n", decoded.length, outputPath);
} catch (IOException e) {
System.err.println("File error: " + e.getMessage());
} catch (IllegalArgumentException e) {
System.err.println("Invalid Base64: " + e.getMessage());
}
}
}Decodificando um campo Base64 de uma resposta HTTP de API
APIs cloud (AWS KMS, GitHub Contents, Vault) frequentemente retornam dados binários como strings Base64 dentro de JSON. Analise o JSON primeiro e depois decodifique o campo desejado:
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class DecodeApiResponse {
public static void main(String[] args) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/secrets/db-password"))
.header("Authorization", "Bearer sk-prod-9f8e7d6c")
.build();
try {
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
System.err.printf("Unexpected status: %d%n", response.statusCode());
return;
}
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.body());
// API retorna: {"name":"db-password","value":"cG9zdGdyZXM6eGs5...","version":3}
String encodedValue = root.get("value").asText();
byte[] decoded = Base64.getDecoder().decode(encodedValue);
String secret = new String(decoded, StandardCharsets.UTF_8);
System.out.println("Secret: " + secret);
// Secret: postgres:xk9mP2qR@db-prod:5432/orders
} catch (Exception e) {
System.err.println("Failed to fetch secret: " + e.getMessage());
}
}
}IllegalArgumentException separadamente dos erros de rede. Misturar exceções de I/O com falhas de decodificação dificulta a depuração — você quer saber imediatamente se a API retornou dados inválidos ou se a rede falhou.Decodificação Base64 pela Linha de Comando
Nem sempre é necessário um programa Java. Todos os sistemas Linux e macOS têm o comando base64, e o JDK 9+ inclui o jshell para one-liners Java interativos. Para inspeção rápida durante a depuração, esses são mais ágeis do que compilar uma classe.
# Decodificar uma string Base64 (Linux / macOS)
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode
# {"host":"10.0.1.50","port":8443}
# Decodificar e formatar com jq
echo "eyJob3N0IjoiMTAuMC4xLjUwIiwicG9ydCI6ODQ0M30=" | base64 --decode | jq .
# {
# "host": "10.0.1.50",
# "port": 8443
# }
# Decodificação rápida com jshell (JDK 9+)
echo 'System.out.println(new String(java.util.Base64.getDecoder().decode("c2VydmVyLWNvbmZpZw==")))' | jshell -
# server-config
# macOS usa -D em vez de --decode
echo "c2VydmVyLWNvbmZpZw==" | base64 -DPara colar strings codificadas diretamente no navegador, o decodificador Base64 do ToolDeck lida com as variantes padrão e URL-safe sem nenhuma configuração.
Alternativa de Alta Performance: Apache Commons Codec
O java.util.Base64 nativo do Java já é bem otimizado — o JDK 11+ usa intrinsics em x86 para codificação e decodificação. Para a maioria das aplicações, não há motivo para recorrer a uma biblioteca de terceiros. Dito isso, o Apache Commons Codec continua popular em bases de código legadas e oferece Base64InputStream para decodificação em streaming com tratamento automático de espaços em branco.
<!-- pom.xml -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.17.0</version>
</dependency>import org.apache.commons.codec.binary.Base64;
public class CommonsCodecDecode {
public static void main(String[] args) {
// Commons Codec é mais permissivo — lida com espaços e quebras de linha
String encoded = "eyJob3N0IjoiMTAuMC4xLjUw\nIiwicG9ydCI6ODQ0M30=";
byte[] decoded = Base64.decodeBase64(encoded);
System.out.println(new String(decoded));
// {"host":"10.0.1.50","port":8443}
}
}A principal vantagem do Commons Codec sobre a API nativa é sua permissividade com espaços em branco por padrão e sua classe Base64InputStream que é anterior ao decoder.wrap() do Java. Se você está no Java 8+, a API nativa cobre tudo que o Commons Codec faz. Eu só recorro ao Commons Codec quando o projeto já depende dele.
Streaming de Arquivos Base64 Grandes com decoder.wrap()
Carregar um arquivo Base64 de 200 MB com Files.readString() e depois chamar decode() aloca aproximadamente 350 MB de heap: a string codificada mais o array de bytes decodificado. decoder.wrap(InputStream) decodifica sob demanda, mantendo o uso de memória constante.
import java.util.Base64;
import java.io.*;
import java.nio.file.*;
public class StreamDecode {
public static void main(String[] args) throws IOException {
Path src = Path.of("database-dump.sql.b64");
Path dst = Path.of("database-dump.sql");
try (InputStream in = Base64.getMimeDecoder().wrap(
new BufferedInputStream(Files.newInputStream(src)));
OutputStream out = new BufferedOutputStream(Files.newOutputStream(dst))) {
byte[] buffer = new byte[8192];
int bytesRead;
long total = 0;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
total += bytesRead;
}
System.out.printf("Decoded %d bytes → %s%n", total, dst);
}
}
}No Java 9+ você pode substituir o loop de leitura por in.transferTo(out) — faz a mesma coisa com menos código. Use getMimeDecoder().wrap() em vez de getDecoder().wrap() se o arquivo puder conter quebras de linha (arquivos PEM, exportações de e-mail).
import java.util.Base64;
import java.io.*;
import java.nio.file.*;
public class StreamDecodeSimple {
public static void main(String[] args) throws IOException {
try (InputStream in = Base64.getMimeDecoder().wrap(
new BufferedInputStream(Files.newInputStream(Path.of("backup.tar.b64"))));
OutputStream out = Files.newOutputStream(Path.of("backup.tar"))) {
in.transferTo(out); // Java 9+
}
}
}getDecoder().wrap() não tolera quebras de linha no stream. Se os dados Base64 tiverem novas linhas (quebrados a cada 76 chars), use getMimeDecoder().wrap() — caso contrário o stream produz saída corrompida silenciosamente ou lança uma exceção em uma posição de leitura imprevisível.Decodificar Payload JWT em Base64 em Java Sem Biblioteca JWT
Um JWT é composto por três segmentos codificados em Base64url separados por pontos. O segmento do meio é o payload — a parte que importa durante a depuração. Você pode decodificá-lo sem importar jjwt ou Nimbus. Divida no ., decodifique a segunda parte com getUrlDecoder() e analise o JSON resultante:
import java.util.Base64;
import java.nio.charset.StandardCharsets;
public class JWTInspect {
public static String decodeJwtPayload(String token) {
String[] parts = token.split("\\.");
if (parts.length != 3) {
throw new IllegalArgumentException(
"Invalid JWT: expected 3 segments, got " + parts.length);
}
// JWT usa Base64 URL-safe sem padding
byte[] payload = Base64.getUrlDecoder().decode(parts[1]);
return new String(payload, StandardCharsets.UTF_8);
}
public static void main(String[] args) {
String token = "eyJhbGciOiJSUzI1NiJ9"
+ ".eyJzdWIiOiJ1c3ItNjcyIiwiaXNzIjoiYXV0aC5leGFtcGxlLmNvbSIs"
+ "ImV4cCI6MTc0MTk1NjgwMCwicm9sZXMiOlsiYWRtaW4iLCJiaWxsaW5nIl19"
+ ".SIGNATURE_PLACEHOLDER";
String payload = decodeJwtPayload(token);
System.out.println(payload);
// {"sub":"usr-672","iss":"auth.example.com",
// "exp":1741956800,"roles":["admin","billing"]}
}
}Erros Comuns
Já encontrei cada um desses em revisões de código, e os dois primeiros respondem pela grande maioria dos bugs de produção relacionados a Base64 em serviços Java.
Problema: Tokens JWT e tokens de acesso OAuth usam o alfabeto URL-safe (- e _). Passá-los para getDecoder() lança IllegalArgumentException porque - não está no alfabeto Base64 padrão.
Solução: Verifique a origem dos seus dados: tokens de sistemas de autenticação precisam de getUrlDecoder(); anexos MIME precisam de getMimeDecoder().
// Cabeçalho JWT — URL-safe, sem padding String header = "eyJhbGciOiJSUzI1NiJ9"; byte[] decoded = Base64.getDecoder().decode(header); // IllegalArgumentException: Illegal base64 character 2d
String header = "eyJhbGciOiJSUzI1NiJ9";
byte[] decoded = Base64.getUrlDecoder().decode(header);
System.out.println(new String(decoded));
// {"alg":"RS256"}Problema: new String(bytes) usa o charset padrão da JVM, que difere entre ambientes. Um servidor Linux de CI (UTF-8) e um host Windows de produção (Cp1252) produzem resultados diferentes para os mesmos bytes.
Solução: Sempre passe StandardCharsets.UTF_8 como segundo argumento.
byte[] decoded = Base64.getDecoder().decode(encoded); String result = new String(decoded); // dependente da plataforma — pode corromper caracteres multibyte
byte[] decoded = Base64.getDecoder().decode(encoded); String result = new String(decoded, StandardCharsets.UTF_8); // consistente em todas as plataformas
Problema: Strings Base64 coladas de terminais ou lidas de arquivos de configuração frequentemente têm novas linhas no final. O decodificador básico rejeita qualquer caractere fora do alfabeto Base64.
Solução: Chame .strip() na entrada antes de decodificar, ou mude para getMimeDecoder() que ignora espaços em branco.
// Lido de variável de ambiente — tem uma nova linha no final
String encoded = System.getenv("DB_PASSWORD_B64"); // "cG9zdGdyZXM=
"
byte[] decoded = Base64.getDecoder().decode(encoded);
// IllegalArgumentException: Illegal base64 character aString encoded = System.getenv("DB_PASSWORD_B64");
byte[] decoded = Base64.getDecoder().decode(encoded.strip());
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// postgresProblema: Chamar new String(decoded) em conteúdo binário (imagens, protobuf, blobs criptografados) produz uma String inválida. Convertê-la de volta para bytes posteriormente corrompe os dados silenciosamente porque o construtor String substitui sequências UTF-8 inválidas.
Solução: Mantenha os dados binários como byte[] em todo o seu pipeline. Converta para String somente quando tiver certeza de que o conteúdo é texto.
byte[] decoded = Base64.getDecoder().decode(pngBase64);
String imageStr = new String(decoded); // corrompe o binário
Files.writeString(Path.of("image.png"), imageStr); // arquivo quebradobyte[] decoded = Base64.getDecoder().decode(pngBase64);
// Escrever bytes diretamente — sem conversão para String
Files.write(Path.of("image.png"), decoded);Comparação de Métodos
Os decodificadores nativos cobrem a maioria dos casos de uso. Apache Commons Codec e Guava são alternativas que você pode encontrar em bases de código mais antigas.
Para tokens JWT e payloads de APIs modernas: getUrlDecoder(). Para anexos de e-mail e certificados PEM: getMimeDecoder(). Para arquivos grandes onde a memória importa: decoder.wrap(InputStream). Para todo o resto: getDecoder(). Apache Commons Codec faz sentido apenas se já estiver na sua árvore de dependências.
Para verificação rápida durante o desenvolvimento, o decodificador Base64 online é mais ágil do que escrever uma classe avulsa.
Perguntas Frequentes
Como decodificar uma string Base64 em Java?
Importe java.util.Base64 e chame Base64.getDecoder().decode(encodedString). O método retorna um byte[] — envolva-o com new String(bytes, StandardCharsets.UTF_8) para obter texto legível. Para Base64 URL-safe (usado em JWTs), substitua getDecoder() por getUrlDecoder().
import java.util.Base64;
import java.nio.charset.StandardCharsets;
byte[] decoded = Base64.getDecoder().decode("c2VydmVyLWNvbmZpZw==");
String result = new String(decoded, StandardCharsets.UTF_8);
System.out.println(result); // server-configQual é a diferença entre getDecoder() e getMimeDecoder() em Java?
getDecoder() é rigoroso — rejeita qualquer caractere fora do alfabeto Base64, incluindo quebras de linha. getMimeDecoder() tolera separadores de linha (\r\n) e ignora qualquer caractere que não seja Base64, sendo a escolha certa para decodificar anexos de e-mail e certificados PEM onde os dados são quebrados a cada 76 caracteres.
String wrapped = "c2VydmVyLWNv\r\nbmZpZw=="; // getDecoder() lança IllegalArgumentException // Base64.getDecoder().decode(wrapped); // FALHA // getMimeDecoder() lida com isso byte[] decoded = Base64.getMimeDecoder().decode(wrapped); System.out.println(new String(decoded)); // server-config
Como decodificar uma string Base64 URL-safe em Java?
Use Base64.getUrlDecoder().decode(encoded). O decodificador URL espera o alfabeto - e _ definido na RFC 4648 §5 em vez de + e /. Tokens JWT sempre usam esse alfabeto. Se os caracteres de padding (=) foram removidos (comum em JWTs), o decodificador URL ainda lida com isso — o decodificador URL do Java aceita tanto entradas com quanto sem padding.
import java.util.Base64;
// Cabeçalho JWT — URL-safe, sem padding
String jwtHeader = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";
byte[] decoded = Base64.getUrlDecoder().decode(jwtHeader);
System.out.println(new String(decoded));
// {"alg":"HS256","typ":"JWT"}Como fazer decodificação em streaming de um arquivo Base64 grande em Java?
Use decoder.wrap(inputStream) para envolver um FileInputStream. O InputStream retornado decodifica Base64 sob demanda conforme você lê os bytes, mantendo o uso de memória constante independentemente do tamanho do arquivo. Passe-o por um BufferedInputStream ou diretamente para Files.copy() para melhor desempenho.
import java.util.Base64;
import java.io.*;
import java.nio.file.*;
try (InputStream in = Base64.getDecoder().wrap(
new BufferedInputStream(new FileInputStream("payload.b64")));
OutputStream out = new FileOutputStream("payload.bin")) {
in.transferTo(out);
}Por que Base64.getDecoder().decode() lança IllegalArgumentException?
O decodificador básico é rigoroso: rejeita quebras de linha, espaços e qualquer caractere fora de A-Za-z0-9+/=. Três causas comuns: a entrada tem quebras de linha no final (use trim), a entrada usa caracteres URL-safe como - e _ (mude para getUrlDecoder()), ou a entrada está quebrada a cada 76 caracteres (mude para getMimeDecoder()). Sempre inspecione os bytes brutos se a mensagem de erro não estiver clara.
String raw = "c2VydmVyLWNvbmZpZw==\n"; // quebra de linha no final // Opção 1: remover espaços em branco byte[] decoded = Base64.getDecoder().decode(raw.strip()); // Opção 2: usar decodificador MIME que ignora espaços em branco byte[] decoded2 = Base64.getMimeDecoder().decode(raw);
Posso decodificar Base64 em Java sem java.util.Base64?
Sim, mas não há motivo para isso no Java 8+. Antes do Java 8, os desenvolvedores usavam sun.misc.BASE64Decoder (interno, removido no Java 9+), javax.xml.bind.DatatypeConverter.parseBase64Binary() (removido no Java 11) ou Apache Commons Codec. Todos os três estão depreciados ou exigem uma dependência extra. Use java.util.Base64 — é mais rápido, acompanha o JDK e cobre as três variantes (básico, URL-safe, MIME).
Ferramentas Relacionadas
- Codificador Base64 — codifique texto ou dados binários em Base64 no navegador, útil para gerar fixtures de teste para colar nos seus testes unitários Java.
- Decodificador JWT — divida e decodifique os três segmentos do JWT de uma vez, com inspeção campo a campo do payload — mais rápido do que escrever uma classe Java quando você só precisa ler um token.
- Decodificador de URL — decodifique strings com percent-encoding, útil quando respostas de API combinam dados Base64url com parâmetros de query percent-encoded.
- Formatador JSON — após decodificar um payload JWT ou configuração de API em Base64, cole o JSON aqui para formatar e validar a estrutura.