Skip to content

Guide

Codificação Base64 explicada: por que, quando e as variantes comuns

Um alfabeto de 64 caracteres, uma penalidade de tamanho de 33% e três variantes que parecem quase idênticas até se quebrarem mutuamente.

By Published

Base64 está em todo lugar — anexos de e-mail, tokens JWT, URIs de dados, blocos PEM de certificados, segredos de clientes OAuth, payloads de notificações push — e quase ninguém para para perguntar o que está realmente fazendo. Ele faz um trabalho específico, tem três variantes quase idênticas e as diferenças entre elas causam a maioria dos bugs.

Qual problema o Base64 resolve

Muitos canais de transporte são projetados para texto, não para bytes arbitrários. Corpos de e-mail historicamente tinham que ser ASCII imprimível. URLs não podem conter caracteres de controle brutos ou espaços. Strings JSON devem ser Unicode válido. Se você quiser enviar um PNG dentro de qualquer um desses, os bytes brutos quebrarão o canal.

O Base64 pega qualquer sequência de bytes e a re-expressa usando apenas 64 caracteres seguros mais preenchimento opcional. O resultado cabe em qualquer lugar que o texto caiba, e um decodificador recupera os bytes originais exatamente. Não há perda, nenhuma compressão e nenhuma segurança — apenas uma mudança de formato.

O alfabeto

Base64 padrão (RFC 4648 §4) usa 65 caracteres no total:

  • A–Z — valores 0–25
  • a–z — valores 26–51
  • 0–9 — valores 52–61
  • + — valor 62
  • / — valor 63
  • = — preenchimento, sem valor

Cada caractere carrega 6 bits (porque 26 = 64). Três bytes de entrada (24 bits) mapeiam para quatro caracteres de saída (24 bits). Quando a entrada não é um múltiplo de 3 bytes, o codificador preenche com zeros à direita e emite = para cada etapa de preenchimento.

Por que a saída é 33% maior

4 caracteres de saída carregam apenas o que 3 bytes de entrada carregavam, então a inflação é exatamente 4/3 = 1,333…, ou 33,3% a mais. Um arquivo binário de 1 MB se torna uma string Base64 de 1,33 MB. Este é o custo pelo transporte seguro de texto.

Experimente nosso codificador / decodificador Base64 com uma entrada de exemplo — você verá a proporção de tamanho relatada junto com o resultado.

As três variantes que você encontrará

Base64 padrão (RFC 4648 §4)

O original. Alfabeto inclui + e /, preenchimento com = obrigatório. Usado por arquivos PEM (certificados TLS, chaves SSH), XML Signature, anexos SOAP e o cabeçalho HTTP Authorization: Basic.

Base64url (RFC 4648 §5)

Seguro para URL e nome de arquivo. Substitui + por - e / por _. O preenchimento é tecnicamente opcional na especificação, mas quase sempre omitido na prática. Isso é o que JWT, JWS, JWE, PKCE do OAuth, VAPID do WebPush e WebAuthn usam.

Base64 padrão e URL-safe não são diretamente intercambiáveis. Veja nossa comparação Base64 vs Base64url para as regras exatas.

MIME Base64 (RFC 2045)

A variante original de anexo de e-mail. Mesmo alfabeto que Base64 padrão, mas com uma quebra de linha rígida (\r\n) inserida a cada 76 caracteres porque relés SMTP antigos engasgavam em linhas longas. Se você está gerando Base64 para um campo JSON ou JWT, nunca insira quebras de linha.

Onde o Base64 aparece na prática

  • Tokens JWT — três seções base64url (sem preenchimento) unidas por pontos.
  • Auth Básica HTTPusuario:senha codificado em Base64 padrão, enviado no cabeçalho Authorization.
  • URIs de dadosdata:image/png;base64,iVBORw0KG… incorpora o binário diretamente em HTML ou CSS.
  • Arquivos PEM — certificados TLS, chaves SSH, mensagens PGP. Base64 padrão envolto em cabeçalhos -----BEGIN…-----.
  • Anexos de e-mail — MIME Base64 com quebra de linha de 76 caracteres.
  • Secrets do Kubernetes — recursos Secret são valores codificados em Base64 padrão (o que confunde pessoas a pensar que estão criptografados).

Armadilhas comuns

Codificando strings sem especificar UTF-8

Base64 não sabe sobre caracteres — ele codifica bytes. Se você fizer Base64 da string “café”, o resultado depende inteiramente de qual codificação de bytes você escolheu (UTF-8 dá 5 bytes produzindo Y2Fmw6k=; Latin-1 dá 4 bytes produzindo Y2Fm6Q==). Decodificar com uma suposição diferente dá lixo.

Misturando padrão e URL-safe

Uma string contendo - ou _ é base64url; decodificadores Base64 padrão a rejeitam. Uma string contendo + ou / é padrão; decodificadores URL-safe a rejeitam. Se você controla ambas as extremidades, escolha uma e documente.

Incompatibilidade de preenchimento

JWTs e formatos similares eliminam o preenchimento. Decodificadores ingênuos exigem preenchimento e lançam InvalidBase64. A correção é re-adicionar caracteres = até que o comprimento da entrada seja um múltiplo de 4.

Tratar Base64 como um limite de segurança

Secrets do Kubernetes são Base64, não criptografados. Fazer Base64 de uma senha no código do cliente não a protege. Base64 não esconde nada de ninguém com um decodificador — e cada laptop tem um.

Inchaço do URI de dados

Inline de uma imagem de 200 KB com Base64 a aumenta para 266 KB e bloqueia a thread principal enquanto o navegador analisa o URI. Para qualquer coisa além de alguns KB, sirva o arquivo de uma URL normal e deixe o navegador armazená-lo em cache.

Experimente o codificador

Cole qualquer texto ou faça upload de um arquivo em nosso codificador / decodificador Base64. Ele suporta alfabetos padrão e URL-safe, mostra o comportamento de preenchimento explicitamente e relata tamanhos de bytes de entrada/saída. A entrada do glossário Base64 é a versão em um parágrafo.

Conclusão

Base64 é uma conveniência de transporte, não um recurso de segurança. Custa um terço dos seus bytes e paga de volta em compatibilidade com canais somente de texto. As variantes importam — padrão para PEM e HTTP Basic, URL-safe para JWTs e OAuth, MIME para e-mail — e elas não se decodificam mutuamente sem transcodificação. Sempre seja explícito sobre qual variante você produz e consome, e sempre codifique strings Unicode para bytes UTF-8 primeiro.

Frequently asked questions

Base64 é criptografia?
Não. Base64 é codificação, não criptografia — não há chave, e qualquer pessoa pode revertê-lo instantaneamente. Ele existe para tornar dados binários transportáveis com segurança por canais somente de texto (corpos de e-mail, JSON, URLs). Tratar Base64 como uma medida de segurança é uma vulnerabilidade, não uma defesa.
Por que a saída codificada é sempre maior do que a entrada?
Cada caractere Base64 carrega apenas 6 bits de informação; um byte de entrada carrega 8. Então cada 3 bytes de entrada se tornam 4 caracteres de saída — uma inflação de 4/3 (≈33%). Com preenchimento, entradas muito curtas são arredondadas para o próximo múltiplo de 4, adicionando mais alguns bytes.
Qual é a diferença entre Base64 e Base64url?
Dois caracteres no alfabeto. O Base64 padrão usa ‘+’ e ‘/’ para os últimos dois dos 64 símbolos, mais ‘=’ para preenchimento. O Base64url substitui ‘+’ por ‘-’ e ‘/’ por ‘_’ para que a saída seja segura para colocar em URLs e nomes de arquivos sem mais escape. JWTs também omitem o preenchimento ‘=’ inteiramente.
Por que o preenchimento (=) às vezes aparece e às vezes não?
O preenchimento torna o comprimento da saída um múltiplo de 4 — exigido por alguns decodificadores estritos. Padrões web modernos (JWT, PKCE do OAuth, WebPush) eliminam o preenchimento porque o comprimento sempre pode ser inferido. Se você está passando uma string para um decodificador desconhecido, inclua o preenchimento; se você está produzindo JWTs ou qualquer coisa correspondendo ao RFC 4648 §5, omita-o.
Base64 pode lidar diretamente com strings Unicode?
Não — Base64 codifica bytes, não caracteres. Para codificar em Base64 uma string Unicode, você primeiro a codifica em bytes (UTF-8 é a escolha universal), então faz Base64 desses bytes. Esquecer essa etapa é a fonte de cada bug ‘mojibake’ no código de tratamento Base64.
Os URIs de dados (data:image/png;base64,...) são a forma certa de incorporar imagens?
Para ícones pequenos e SVG inline, sim — eles economizam um round trip HTTP. Para qualquer coisa maior que alguns KB, não — a inflação de 33% custa mais do que uma requisição separada, os dados não podem ser armazenados em cache independentemente e os navegadores analisam URIs de dados na thread principal, bloqueando a renderização.

Related

Published May 31, 2026