Base64 em Java — Exemplos com java.util.Base64

·Java Security & API Engineer·Revisado porPavel Novak·Publicado

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

Experimentar Codificador Base64 Online online →

Toda vez que configuro um cabeçalho HTTP Basic Auth, incorporo um certificado em um secret do Kubernetes ou envio dados binários por uma API JSON, o primeiro passo é o mesmo: codificar em Base64 os bytes brutos em uma string segura para ASCII. O Java torna isso direto com java.util.Base64, a API padrão disponível desde o Java 8 que substituiu o deprecated sun.misc.BASE64Encoder. Para uma codificação pontual sem escrever código, o Base64 Encoder do ToolDeck resolve na hora pelo navegador. Este guia cobre Base64.getEncoder(), getUrlEncoder(), getMimeEncoder(), codificação de arquivos, streaming com wrap(OutputStream), e os erros que surpreendem até desenvolvedores Java experientes. Todos os exemplos compilam no Java 8 ao Java 21+.

  • Base64.getEncoder().encodeToString(bytes) é o one-liner padrão — integrado ao JDK desde o Java 8, sem alterações no Java 17 e 21.
  • Sempre passe StandardCharsets.UTF_8 para String.getBytes() antes de codificar — omitir usa o padrão da plataforma, que varia entre JVMs.
  • getUrlEncoder() produz saída URL-safe (- em vez de +, _ em vez de /) e withoutPadding() remove os caracteres = de padding.
  • getMimeEncoder() insere quebras de linha a cada 76 caracteres — obrigatório para e-mail (MIME) e formatos de certificado PEM.
  • Para arquivos grandes, use Base64.getEncoder().wrap(OutputStream) para transmitir em streaming sem carregar o arquivo inteiro na memória.

O que é Codificação Base64?

Base64 converte dados binários arbitrários em uma string composta por 64 caracteres ASCII imprimíveis: A-Z, a-z, 0-9, + e /. Cada 3 bytes de entrada produzem exatamente 4 caracteres Base64. Se o comprimento da entrada não for múltiplo de 3, um ou dois caracteres de padding = são adicionados. O resultado codificado é sempre aproximadamente 33% maior que os dados originais.

Base64 não é criptografia. Qualquer pessoa com a string codificada pode decodificá-la. Sua finalidade é a segurança no transporte: cabeçalhos HTTP, payloads JSON, documentos XML e corpos de e-mail são protocolos baseados em texto que não conseguem transportar bytes binários brutos sem corrupção. Os casos de uso comuns no Java incluem HTTP Basic Authentication, incorporação de certificados PEM, armazenamento de dados binários em colunas de texto de banco de dados e construção de segmentos de tokens JWT.

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

Base64.getEncoder().encodeToString() — A API Padrão

java.util.Base64 foi introduzido no Java 8 como substituto oficial do sun.misc.BASE64Encoder. A classe fornece três métodos de fábrica estáticos — cada um retornando uma instância da classe aninhada Base64.Encoder — cobrindo as três variantes Base64 definidas na RFC 4648. Nenhuma biblioteca de terceiros é necessária. Nenhuma dependência Maven. Basta importar e chamar.

Exemplo Mínimo — Codificar uma String

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

O passo-chave que a maioria dos desenvolvedores Java erra na primeira tentativa: uma String precisa ser convertida em byte[] antes de codificar. Base64 opera sobre bytes, não sobre caracteres. encodeToString() aceita um byte[] e retorna a String Base64 diretamente. Se você precisar do resultado codificado como bytes em vez de uma string, use encode(byte[]) — isso retorna um byte[] dos caracteres Base64 codificados em ASCII, útil quando você está escrevendo diretamente em um OutputStream ou construindo frames de protocolo binário.

HTTP Basic Auth — O Caso de Uso Mais Comum

A HTTP Basic Authentication é provavelmente a razão mais comum pela qual desenvolvedores Java recorrem à codificação Base64. A especificação (RFC 7617) exige que a string de credenciais username:password seja codificada em Base64 e inserida no cabeçalho Authorization. Já vi isso feito errado mais vezes do que posso contar — geralmente por esquecer o separador de dois pontos ou codificar os componentes separadamente.

Java — cabeçalho HTTP Basic Auth
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
    }
}

Ida e Volta — Codificar e Decodificar

Java 8+ — encode e decode de ida e volta
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";

        // Codificar
        String encoded = Base64.getEncoder()
            .encodeToString(original.getBytes(StandardCharsets.UTF_8));
        System.out.println(encoded);
        // WC1Db3JyZWxhdGlvbi1JRDogcmVxXzhhNGYyYzkxLWU3YjMtNGQ1Ni05MDEyLTNmN2E4YjljMGQxZQ==

        // Decodificar
        byte[] decodedBytes = Base64.getDecoder().decode(encoded);
        String decoded = new String(decodedBytes, StandardCharsets.UTF_8);

        System.out.println(original.equals(decoded));  // true
    }
}
Nota:A API java.util.Base64 é idêntica do Java 8 ao Java 17 e Java 21. Nenhuma migração é necessária ao atualizar o JDK. O mesmo código compila e executa em qualquer versão desde o Java 8.

Codificando Dados Não-String — byte[], UUID e Timestamps

A codificação Base64 no Java sempre começa com um byte[]. Strings se convertem via getBytes(StandardCharsets.UTF_8), mas outros tipos precisam de uma etapa de conversão antes. UUIDs, timestamps e identificadores numéricos precisam ser serializados para uma string ou representação em bytes antes de poderem ser codificados em Base64.

UUID — Codificar como Representação String

Java — codificação Base64 de um 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

UUID Compacto — Codificar os 16 Bytes Brutos

Se você quiser um resultado codificado mais curto, extraia os 128 bits do UUID como 16 bytes brutos em vez de converter para sua forma de string de 36 caracteres. A saída Base64 cai de 48 para 24 caracteres.

Java — codificação compacta de UUID
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 chars vs 48 para a abordagem baseada em string

Timestamp e Payload Misto

Java — codificando um payload semelhante a JSON com timestamp
import java.time.Instant;
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simulando um payload estilo 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, sem padding)
Aviso:Não chame toString() em um byte[] esperando ver seu conteúdo — isso retorna o hash de identidade do array, como [B@6d06d69c. Use new String(bytes, StandardCharsets.UTF_8) ou passe o array de bytes diretamente para encodeToString().

Referência dos Métodos de Base64.Encoder

A classe java.util.Base64 expõe três métodos de fábrica, cada um retornando um Base64.Encoder configurado para uma variante específica. As instâncias do encoder são thread-safe e sem estado — crie-as uma vez e reutilize.

Método
Tipo
Descrição
getEncoder()
Base64.Encoder
Retorna um encoder básico RFC 4648 usando o alfabeto padrão (A-Z, a-z, 0-9, +, /)
getUrlEncoder()
Base64.Encoder
Retorna um encoder com o alfabeto URL-safe (- em vez de +, _ em vez de /)
getMimeEncoder()
Base64.Encoder
Retorna um encoder MIME que insere quebras de linha \r\n a cada 76 caracteres
getMimeEncoder(lineLength, lineSeparator)
Base64.Encoder
Encoder MIME com comprimento de linha e bytes separadores personalizados
encoder.withoutPadding()
Base64.Encoder
Retorna um encoder que omite os caracteres de padding = no final
encoder.encode(byte[])
byte[]
Codifica um array de bytes e retorna um array de bytes codificado
encoder.encodeToString(byte[])
String
Codifica um array de bytes e retorna uma String codificada diretamente
encoder.wrap(OutputStream)
OutputStream
Envolve um OutputStream para codificação Base64 em streaming

Base64.getUrlEncoder() — Codificação URL-Safe

O encoder URL-safe usa um alfabeto alternativo onde + vira - e / vira _, conforme definido na RFC 4648 Seção 5. Isso é importante sempre que a string Base64 aparecer em um parâmetro de query de URL, nome de arquivo ou valor de cookie — os caracteres Base64 padrão conflitam com delimitadores de URL e caracteres reservados do sistema de arquivos.

Java — codificação Base64 URL-safe
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 padrão — contém + e / que quebram URLs
String standard = Base64.getEncoder().encodeToString(data);
System.out.println(standard);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s/c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// Encoder URL-safe — seguro para parâmetros de query e nomes de arquivo
String urlSafe = Base64.getUrlEncoder().encodeToString(data);
System.out.println(urlSafe);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw==

// URL-safe sem padding — para JWTs e tokens compactos
String noPadding = Base64.getUrlEncoder().withoutPadding().encodeToString(data);
System.out.println(noPadding);
// aHR0cHM6Ly9hcHAuaW50ZXJuYWwvY2FsbGJhY2s_c3RhdGU9YXV0aF9wZW5kaW5nJm5vbmNlPTlmMmE3Yw

A variante withoutPadding() remove os caracteres de padding = do final. As especificações JWT exigem Base64 URL-safe sem padding para os segmentos de cabeçalho e payload, portanto getUrlEncoder().withoutPadding() é a chamada exata que você quer ao construir ou manipular tokens JWT manualmente.

Nota:O método withoutPadding() retorna uma nova instância de encoder — ele não modifica o original. Ambos podem ser atribuídos a campos static final e reutilizados com segurança entre threads.

Codificar a partir de Arquivo e Resposta de API

Os dois cenários mais comuns no mundo real para codificação Base64 em Java: leitura de um arquivo binário do disco (certificados, imagens, pacotes de configuração) e codificação de dados recebidos de uma resposta HTTP.

Codificar um Arquivo em Base64

Java — codificando um arquivo
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

public class FileEncoder {
    public static void main(String[] args) {
        try {
            byte[] fileBytes = Files.readAllBytes(Path.of("certs/server.pem"));
            String encoded = Base64.getEncoder().encodeToString(fileBytes);

            System.out.printf("Original: %d bytes%n", fileBytes.length);
            System.out.printf("Encoded:  %d chars%n", encoded.length());

            // Write encoded content to a text file
            Files.writeString(
                Path.of("certs/server.pem.b64"),
                encoded
            );
        } catch (java.io.IOException e) {
            System.err.println("Failed to read file: " + e.getMessage());
        }
    }
}

Codificar o Corpo de uma Resposta de API

Java 11+ — codificando uma resposta HTTP
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("Encoded %d bytes → %d chars%n",
                    response.body().length, encoded.length());
            } else {
                System.err.printf("HTTP %d: %s%n",
                    response.statusCode(),
                    new String(response.body()));
            }
        } catch (Exception e) {
            System.err.println("Request failed: " + e.getMessage());
        }
    }
}

Uma nota rápida antes da seção de linha de comando: se você só precisa colar um arquivo ou resposta de API e obter o resultado Base64 sem escrever código, o Base64 Encoder online aceita tanto entradas de texto quanto binárias.

Codificação Base64 pela Linha de Comando

Às vezes você só precisa codificar uma string ou arquivo pelo terminal — sem projeto Java, sem IDE, sem etapa de build. A maioria dos sistemas Unix vem com o comando base64 e, se você tiver um JDK instalado, pode usar o jshell para uma abordagem nativa em Java.

Bash — codificação Base64 pela linha de comando
# macOS / Linux — codificar uma string
echo -n "deploy-bot:sk_prod_9f2a7c4e" | base64
# ZGVwbG95LWJvdDpza19wcm9kXzlmMmE3YzRl

# Codificar um arquivo
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 diretamente com um one-liner
java -e 'System.out.println(java.util.Base64.getEncoder().encodeToString(args[0].getBytes()))' "my-secret"
# Nota: java -e requer JDK 23+ (JEP 477)

A abordagem com jshell é especialmente útil quando você precisa verificar que seu código Java produz a mesma saída que uma ferramenta Unix, ou quando está depurando uma divergência entre o que seu serviço envia e o que o receptor espera. Tenho um alias de shell para isso.

Nota:No macOS, o comando base64 usa -D para decodificação. No Linux (GNU coreutils) usa -d. O comportamento de codificação é idêntico em ambos. O flag -w 0 no Linux desativa a quebra de linha na saída, o que geralmente é o que você quer ao redirecionar para outros comandos.

Apache Commons Codec — Alternativa de Alto Desempenho

Para a maioria das aplicações, java.util.Base64 é rápido o suficiente. Mas se você está processando milhões de operações de codificação em um loop apertado — como pipelines de ingestão de logs ou brokers de mensagens de alto throughput — o Apache Commons Codec vale a pena testar. Ele existe desde muito antes do Java 8 e oferece uma alternativa battle-tested com uma superfície de API ligeiramente diferente.

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

// Codificação padrão
String encoded = Base64.encodeBase64String(telemetryPayload);

// Codificação URL-safe
String urlSafe = Base64.encodeBase64URLSafeString(telemetryPayload);

// Verificar se uma string é Base64 válido
boolean valid = Base64.isBase64(encoded);
System.out.println(valid);  // true

O Apache Commons Codec também fornece Base64OutputStream e Base64InputStream para cenários de streaming, além de um método de validação que o encoder do JDK não possui. Se o Commons Codec já estiver na sua árvore de dependências (ele vem com muitos projetos Apache), não há razão para não usá-lo.

Guava BaseEncoding

A biblioteca Guava do Google inclui BaseEncoding, que oferece uma API fluente para Base64 com separadores de linha configuráveis, controle de padding e suporte a alfabetos padrão e URL-safe. A API é legível, mas adicionar Guava (cerca de 3 MB) apenas para codificação Base64 é exagero. Se o Guava já estiver no seu projeto para coleções ou utilitários de cache, a API de codificação é um bônus bem-vindo.

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

// Base64 padrão
String standard = BaseEncoding.base64().encode(webhookPayload);

// URL-safe
String urlSafe = BaseEncoding.base64Url().encode(webhookPayload);

// Sem padding
String noPad = BaseEncoding.base64Url().omitPadding().encode(webhookPayload);

// Com separadores de linha (estilo PEM)
String wrapped = BaseEncoding.base64()
    .withSeparator("\n", 64)
    .encode(webhookPayload);

Base64.getMimeEncoder() — Saída MIME e PEM com Quebra de Linha

O encoder MIME insere quebras de linha \r\n a cada 76 caracteres, atendendo à especificação MIME (RFC 2045). Certificados PEM, anexos de e-mail S/MIME e algumas APIs legadas esperam esse formato. Os encoders padrão e URL-safe produzem uma única linha ininterrupta — se você passar o resultado deles para um sistema que espera Base64 com quebra de linha, ele pode falhar silenciosamente ou rejeitar os dados.

Java — codificação Base64 MIME
import java.util.Base64;
import java.nio.charset.StandardCharsets;

// Simular o corpo de um certificado PEM
byte[] certData = new byte[256];  // Na prática, leia de um arquivo .der
new java.security.SecureRandom().nextBytes(certData);

// Encoder MIME padrão — 76 chars por linha, separador \r\n
String mimeEncoded = Base64.getMimeEncoder().encodeToString(certData);
System.out.println(mimeEncoded);
// QYx2K3p8Xg7JmN1R+wFkLd...  (76 chars)
// Ht5Bv9CzAq0PnSjYl8WxUe...  (76 chars)
// ...

// Encoder MIME personalizado — 64 chars por linha (padrão PEM), separador \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-----");
Aviso:Não use getMimeEncoder() para tokens JWT, cabeçalhos HTTP ou parâmetros de URL. As quebras de linha vão corromper os dados nesses contextos. Use getEncoder() ou getUrlEncoder() em vez disso.

Streaming de Arquivos Grandes com Base64.getEncoder().wrap()

Carregar um arquivo inteiro em um byte[] com Files.readAllBytes() funciona para arquivos pequenos, mas para qualquer coisa acima de 50-100 MB você arrisca um OutOfMemoryError. O JDK oferece Base64.getEncoder().wrap(OutputStream), que retorna um OutputStream que codifica os dados em tempo real à medida que você escreve nele. Os bytes codificados fluem para o stream subjacente sem armazenar toda a entrada em buffer.

Java — codificação Base64 em streaming
import java.io.*;
import java.nio.file.*;
import java.util.Base64;

public class StreamingEncoder {
    public static void main(String[] args) throws IOException {
        Path inputPath = Path.of("backups/database-export.sql.gz");
        Path outputPath = Path.of("backups/database-export.sql.gz.b64");

        try (
            InputStream in = Files.newInputStream(inputPath);
            OutputStream fileOut = Files.newOutputStream(outputPath);
            OutputStream base64Out = Base64.getEncoder().wrap(fileOut)
        ) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            long totalBytes = 0;

            while ((bytesRead = in.read(buffer)) != -1) {
                base64Out.write(buffer, 0, bytesRead);
                totalBytes += bytesRead;
            }

            System.out.printf("Streamed %d bytes through Base64 encoder%n", totalBytes);
        }
        // Fechar base64Out descarrega os bytes finais de padding automaticamente
    }
}

O bloco try-with-resources cuida do flush e do fechamento. Um detalhe que pega as pessoas: o padding final do Base64 só é escrito quando o OutputStream de envolvimento é fechado. Se você esquecer de fechá-lo (ou fechar apenas o stream externo), os últimos caracteres da sua saída codificada podem estar faltando.

Streaming para um Socket de Rede

O método wrap() funciona com qualquer OutputStream — saída de arquivo, saída de socket, corpo de resposta HTTP, até ByteArrayOutputStream. Aqui está um exemplo que escreve dados codificados em Base64 diretamente em um buffer em memória, útil para testes unitários ou construção de payloads que serão enviados via HTTP:

Java — streaming para 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)) {
    // Escrever dados em partes — simula leitura de um 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=

// Verificar ida e volta
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
Nota:O tamanho do buffer no exemplo de streaming (8192 bytes) não é arbitrário. Ele corresponde ao tamanho padrão de buffer usado pelo BufferedInputStream e é um bom equilíbrio entre uso de memória e overhead de chamadas de sistema. Buffers menores aumentam o número de chamadas de leitura/escrita; buffers maiores desperdiçam memória sem melhora significativa de throughput.

Instâncias de Encoder Thread-Safe — Armazenar e Reutilizar

O Base64.Encoder retornado pelos métodos de fábrica é imutável e thread-safe. Chamar Base64.getEncoder() a cada operação de codificação cria um novo objeto toda vez. A JVM provavelmente otimizará isso, mas armazenar o encoder em um campo static final deixa a intenção clara e evita alocações desnecessárias em caminhos críticos.

Java — instâncias de encoder reutilizáveis
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class TokenService {
    // Criar uma vez, reutilizar em todo lugar — 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);
    }
}

Esse padrão é especialmente útil em serviços Spring Boot onde uma classe utilitária gerencia a codificação em múltiplos controllers ou métodos de serviço. A chamada withoutPadding() retorna uma nova instância de encoder, então você pode armazenar as variantes com e sem padding como campos separados. Cada chamada a encodeToString() ou encode() é sem estado — nenhuma sincronização necessária, nenhum estado mutável compartilhado.

Erros Comuns

Chamar getBytes() sem especificar um charset

Problema: String.getBytes() sem argumento de charset usa a codificação padrão da plataforma, que é windows-1252 no Windows, UTF-8 na maioria dos sistemas Linux e varia no macOS. O mesmo código produz saídas Base64 diferentes em máquinas diferentes.

Solução: Sempre passe StandardCharsets.UTF_8 explicitamente.

Before · Java
After · Java
String text = "Ключ доступа: prod-east";
byte[] bytes = text.getBytes();  // padrão da plataforma — imprevisível
String encoded = Base64.getEncoder().encodeToString(bytes);
String text = "Ключ доступа: prod-east";
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(bytes);
Usar o encoder padrão para parâmetros de URL

Problema: Base64.getEncoder() gera os caracteres + e /. Quando colocados em uma query string de URL, + é interpretado como espaço e / como separador de caminho, corrompendo silenciosamente o valor no lado receptor.

Solução: Use Base64.getUrlEncoder() para qualquer valor que apareça em uma URL.

Before · Java
After · Java
// Token em parâmetro de query de URL — vai quebrar
String token = Base64.getEncoder()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
// Codificação URL-safe — sem caracteres + ou /
String token = Base64.getUrlEncoder()
    .withoutPadding()
    .encodeToString(sessionData);
String url = "https://auth.internal/verify?token=" + token;
Decodificar com a variante errada de encoder

Problema: Codificar com getUrlEncoder() e decodificar com getDecoder() (ou vice-versa) lança IllegalArgumentException porque - e _ não são válidos no alfabeto Base64 padrão, e + e / não são válidos no alfabeto URL-safe.

Solução: Sempre decodifique com o decoder correspondente: getUrlDecoder() para URL-safe, getDecoder() para o padrão.

Before · Java
After · Java
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Mais tarde...
byte[] decoded = Base64.getDecoder()  // decoder ERRADO
    .decode(encoded);
// IllegalArgumentException se encoded contiver - ou _
String encoded = Base64.getUrlEncoder()
    .encodeToString(data);
// Mais tarde...
byte[] decoded = Base64.getUrlDecoder()  // decoder correspondente
    .decode(encoded);
Não fechar o OutputStream de wrap()

Problema: O encoder de streaming armazena em buffer até 2 bytes de entrada aguardando um grupo completo de 3 bytes. Se você não fechar o OutputStream de envolvimento, os últimos 1-4 caracteres Base64 (incluindo o padding) nunca são escritos.

Solução: Use try-with-resources ou chame close() explicitamente no stream envolvido antes de ler a saída.

Before · Java
After · Java
ByteArrayOutputStream baos = new ByteArrayOutputStream();
 OutputStream b64os = Base64.getEncoder().wrap(baos);
b64os.write(data);
// baos.toString() está INCOMPLETO — faltam os bytes finais
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (OutputStream b64os = Base64.getEncoder().wrap(baos)) {
    b64os.write(data);
}  // close() descarrega o padding final
String encoded = baos.toString();  // completo

Métodos de Codificação Base64 — Comparação

Método
URL-Safe
Streaming
Quebras de Linha
Tipos Personalizados
Requer Instalação
Base64.getEncoder()
✓ (wrap)
Não (JDK 8+)
Base64.getUrlEncoder()
✓ (wrap)
Não (JDK 8+)
Base64.getMimeEncoder()
✓ (wrap)
✓ (76 chars)
Não (JDK 8+)
Apache Commons Codec
Dependência Maven
Guava BaseEncoding
✓ (configurável)
Dependência Maven
jcmd / CLI base64
✓ (pipe)
N/A
Instalação do sistema

Para a maioria dos projetos: java.util.Base64 é a escolha certa. Zero dependências, integrado ao JDK, thread-safe e cobre todas as três variantes da RFC 4648. Recorra ao Apache Commons Codec apenas se ele já estiver no seu classpath e você precisar do método de validação isBase64() ou do Base64OutputStream para streaming. O BaseEncoding do Guava é uma opção razoável se o seu projeto já depende do Guava, mas adicionar uma dependência de 3 MB só por Base64 é difícil de justificar.

Três cenários, três escolhas: serviço web padrão que precisa de Basic Auth ou codificação JWT? Fique com o JDK. Projeto legado que já puxa Commons Codec via Spring ou Apache HTTP Client? Use-o — não há razão para ter duas bibliotecas Base64 no classpath. Projeto que usa Guava para caching e coleções? Use BaseEncoding pela sua API fluente e limpa. Nunca adicione uma biblioteca só por codificação Base64 — a versão do JDK já é boa o suficiente desde 2014.

Se você precisar verificar rapidamente um resultado codificado sem executar seu código Java, cole no Base64 Encoder para confirmar que a saída corresponde ao que seu código produz.

Perguntas Frequentes

Como codificar uma String em Base64 no Java?

Converta a string em bytes usando getBytes(StandardCharsets.UTF_8) e passe o array de bytes para Base64.getEncoder().encodeToString(). Especifique sempre UTF-8 explicitamente — chamar getBytes() sem charset usa o padrão da plataforma, que varia entre sistemas operacionais e configurações de 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

Qual é a diferença entre Base64.getEncoder() e Base64.getUrlEncoder()?

Ambos codificam em Base64, mas getUrlEncoder() usa o alfabeto URL-safe definido na RFC 4648 Seção 5. Ele substitui + por - e / por _ para que o resultado possa aparecer em URLs e nomes de arquivo sem percent-encoding. O encoder padrão usa + e / que conflitam com parâmetros de query de URL e segmentos de caminho.

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
// (igual aqui, mas com + → - e / → _ quando esses chars aparecem)

java.util.Base64 é igual no Java 8 e no Java 17?

Sim. A API java.util.Base64 não mudou desde que foi introduzida no Java 8. A classe, suas classes internas Encoder e Decoder, e todos os métodos de fábrica (getEncoder, getUrlEncoder, getMimeEncoder) são idênticos no Java 8, 11, 17 e 21. Nenhuma migração ou alteração de código é necessária ao atualizar a versão do JDK.

Java
// Este código compila e executa de forma idêntica do Java 8 ao 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==

Como codificar um arquivo em Base64 no Java?

Leia o arquivo em um array de bytes com Files.readAllBytes(Path) e passe-o para Base64.getEncoder().encodeToString(). Para arquivos grandes que não devem ser carregados inteiramente na memória, use Base64.getEncoder().wrap(OutputStream) para transmitir o resultado codificado em streaming.

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

Por que sun.misc.BASE64Encoder foi descontinuado?

sun.misc.BASE64Encoder era uma classe interna do JDK que nunca fez parte da API pública. Ela ficava no pacote sun.misc, cujo uso a Oracle sempre desaconselhou explicitamente. O Java 8 introduziu java.util.Base64 como substituto oficial, público e suportado. Desde o Java 9 e o sistema de módulos, acessar classes sun.misc gera avisos ou erros dependendo da configuração do JDK.

Java
// Forma antiga — NÃO use, removida nos JDKs modernos
// import sun.misc.BASE64Encoder;
// String encoded = new BASE64Encoder().encode(data);

// Forma correta desde o Java 8
import java.util.Base64;
String encoded = Base64.getEncoder().encodeToString(data);

Como fazer um encode e decode de Base64 de ida e volta no Java?

Codifique com Base64.getEncoder().encodeToString(bytes) e decodifique com Base64.getDecoder().decode(encodedString). Converta o array de bytes decodificado de volta para String usando new String(bytes, StandardCharsets.UTF_8). O processo de ida e volta preserva os dados originais exatamente — desde que você use o mesmo charset tanto em getBytes() quanto em new String().

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

// Codificar
String original = "session_token=eyJhbGciOiJSUzI1NiJ9";
byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(originalBytes);

// Decodificar
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes, StandardCharsets.UTF_8);

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

Ferramentas Relacionadas

  • Base64 DecoderDecodifique strings Base64 de volta ao texto ou formato binário original — a operação inversa da codificação.
  • URL EncoderCodifique strings com percent-encoding para uso seguro em URLs — diferente da codificação Base64 URL-safe, mas frequentemente usada em conjunto.
  • JWT DecoderInspecione tokens JWT cujos segmentos de cabeçalho e payload são JSON codificado em Base64url — decodifique sem precisar de uma biblioteca.
  • JSON FormatterFormate payloads JSON antes ou depois da codificação Base64 — útil ao depurar integrações de API.
Também disponível em: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 NovakRevisor técnico

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.