Base64 Decode Java — Guia de getDecoder().decode()

·Backend Engineer·Revisado porAisha Osei·Publicado

Use o Decodificador Base64 Online gratuito diretamente no seu navegador — sem instalação.

Experimentar Decodificador Base64 Online online →

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.

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

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

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

Java 8+
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}
    }
}
Nota: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

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

Java 8+
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
    }
}
Aviso:Nunca use 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.

Método
Retorna
Tipo de Entrada
Descrição
getDecoder()
Base64.Decoder
Decodificador padrão (RFC 4648 §4, alfabeto + e / com padding =)
getUrlDecoder()
Base64.Decoder
Decodificador URL-safe (RFC 4648 §5, alfabeto - e _ com padding =)
getMimeDecoder()
Base64.Decoder
Decodificador MIME — ignora separadores de linha e caracteres não Base64
decode(String src)
byte[]
String
Decodifica a string de entrada em um novo array de bytes
decode(byte[] src)
byte[]
byte[]
Decodifica o array de bytes de entrada em um novo array de bytes
decode(byte[] src, byte[] dst)
int
byte[] + byte[]
Decodifica no buffer dst pré-alocado, retorna bytes escritos
wrap(InputStream is)
InputStream
InputStream
Retorna um stream que decodifica dados Base64 sob demanda

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.

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

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

Java 11+
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());
        }
    }
}
Nota:Envolva a chamada de decodificação em seu próprio bloco try-catch para 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.

bash
# 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 -D

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

XML (Maven)
<!-- pom.xml -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.17.0</version>
</dependency>
Java 8+
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.

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

Java 9+
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+
        }
    }
}
Aviso: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:

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

Usar getDecoder() em entrada URL-safe

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().

Before · Java
After · Java
// 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"}
Não especificar o charset ao construir a String

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.

Before · Java
After · Java
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
Decodificar uma string com espaços em branco no final

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.

Before · Java
After · Java
// 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 a
String encoded = System.getenv("DB_PASSWORD_B64");
byte[] decoded = Base64.getDecoder().decode(encoded.strip());
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// postgres
Converter dados binários para String

Problema: 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.

Before · Java
After · Java
byte[] decoded = Base64.getDecoder().decode(pngBase64);
String imageStr = new String(decoded); // corrompe o binário
Files.writeString(Path.of("image.png"), imageStr); // arquivo quebrado
byte[] 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.

Método
Variante de Codificação
Ignora Espaços
Streaming
Tipos Personalizados
Requer Instalação
Base64.getDecoder()
Padrão (+, /)
Não (JDK 8+)
Base64.getUrlDecoder()
URL-safe (-, _)
Não (JDK 8+)
Base64.getMimeDecoder()
MIME (quebras de linha OK)
Não (JDK 8+)
decoder.wrap(InputStream)
Qualquer variante
Depende do decodificador
Não (JDK 8+)
Apache Commons Base64InputStream
Padrão / URL-safe
Sim (commons-codec)
Apache Commons Base64.decodeBase64()
Padrão
Sim (commons-codec)
Guava BaseEncoding.base64().decode()
Padrão
Sim (guava)

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().

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

Qual é 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.

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

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

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

Java 8+
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.
Também disponível em:JavaScriptPythonGoC#
PN
Pavel NovakBackend Engineer

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.

AO
Aisha OseiRevisor técnico

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.