Utilo

Base64 explicado: Como funciona, quando usá-lo e quando não

Uma explicação clara da codificação Base64: o algoritmo, o preenchimento, o seguro de URL Base64, URLs de dados, gastos gerais de tamanho, armadilhas do Unicode e equívocos de segurança.

· 5 min de leitura

Base64 aparece em anexos de e-mail, JSON Web Tokens, URLs de dados, segredos Kubernetes, autenticação HTTP Basic e inúmeras APIs que precisam mover dados binários através de canais de texto apenas. É simples uma vez que você vê como funciona, mas muitas vezes é mal usado mais notavelmente como se fosse criptografia. Este artigo explica o algoritmo passo a passo, as variantes comuns e orientações práticas sobre quando o Base64 é a ferramenta certa.

O problema Base64 resolve

Muitos sistemas foram projetados para transportar texto, não bytes arbitrários. O email (SMTP) historicamente suportava apenas ASCII de 7 bits. As strings JSON não podem conter binário bruto. URLs e cabeçalhos HTTP têm conjuntos de caracteres restritos. Se você colocar os bytes brutos de uma imagem em qualquer um deles, alguns bytes serão interpretados como caracteres de controle, terminações de linha ou delimitadores, e os dados ficam corrompidos.

Base64 mapeia bytes arbitrários em 64 caracteres seguros e impressíveis: A–Z, a–z, 0–9, + e /. Qualquer sistema que possa transportar texto simples pode então transportar os dados intactos.

Como funciona a codificação

Base64 processa entrada em grupos de 3 bytes (24 bits) e sai 4 caracteres de 6 bits cada. Como 2 ^ 6 = 64, cada valor de 6 bits seleciona um caractere do alfabeto.

Tome a palavra Man:

  1. Bytes ASCII: M = 77, a = 97, n = 110.
  2. Em binário: 01001101 01100001 01101110.
  3. Dividido em quatro grupos de 6 bits: 010011 010110 000101 101110.
  4. Como números: 19, 22, 5, 46.
  5. Procura no alfabeto: T, W, F, u.

Então Man torna-se TWFu. A decodificação inverte o processo.

Revestimento com =

Quando o comprimento de entrada não é múltiplo de 3, o último grupo é incompleto. Base64 está a acertar:

  • 1 byte restante produz 2 caracteres mais ==.
  • 2 bytes restantes produzem 3 caracteres mais =.

Ma codifica para TWE= e M para TQ==. O preenchimento faz com que o comprimento de saída seja um múltiplo de quatro, o que alguns decodificadores exigem. Outros, especialmente implementações seguras de URL, omitem porque o comprimento já implica quantos bytes estão faltando.

Tamanho das despesas gerais

Todos os 3 bytes se tornam 4 caracteres, então a saída Base64 é cerca de 33% maior do que a entrada, além de preenchimento e, às vezes, quebras de linha (o email MIME envolve linhas em 76 caracteres). Uma imagem de 1 MB se torna aproximadamente 1,37 MB de texto. Essa sobrecarga importa quando você incrusta arquivos grandes em JSON ou HTML.

Base64 seguro para URL

O alfabeto padrão inclui + e /, que têm significados especiais em URLs, e = que é usado em strings de consulta. Base64URL, definido na RFC 4648, substitui + por - e / por _, e geralmente deixa de lado o preenchimento. JWT, muitos tokens de API e teclas push web usam essa variante veja como funciona JWT como exemplo.

Um decodificador padrão falha em - e _, e vice-versa, o que é uma fonte comum de erros de "caracteres inválidos". Um decodificador tolerante [Base64 decoder] ((/tools/base64) aceita ambos os alfabetos e restaura automaticamente o preenchimento em falta.

Texto, bytes e Unicode

Base64 codifica bytes, não caracteres. Para codificar texto, você deve primeiro convertê-lo em bytes com uma codificação de caracteres, quase sempre UTF-8. É aqui que os navegadores tropeçam: o btoa() integrado no JavaScript aceita apenas caracteres na faixa Latin-1, então o btoa("héllo") funciona por acidente e o btoa("你好") produz um erro.

A abordagem correta no JavaScript moderno:

const bytes = new TextEncoder().encode("你好 👋");
const b64 = btoa(String.fromCharCode(...bytes));
const back = new TextDecoder().decode(Uint8Array.from(atob(b64), c => c.charCodeAt(0)));

Outras linguagens explicitam isso: o Python base64.b64encode leva bytes, então você escreve base64.b64encode("你好".encode("utf-8")).

URLs de dados

Um URL de dados incorpora um arquivo diretamente em HTML ou CSS:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." alt="">

Isso salva uma solicitação HTTP, que era valiosa na era HTTP/1.1. Hoje, com o multiplexamento HTTP/2, os trade-offs geralmente favorecem arquivos separados:

  • Os URLs de dados não podem ser armazenados em cache de forma independente; eles são recarregados com cada página ou folha de estilo que os contém.
  • Eles inflam HTML e CSS, que bloqueia a renderização até ser baixado e analisado.
  • A despesa de 33% é aplicável, embora o gzip recupere parte dela.

Use URLs de dados para pequenos ativos pequenos ícones com menos de 1 2 KB, imagens de espaço reservado ou exportações HTML de um único arquivo. Para qualquer coisa maior, sirva um arquivo normal e comprima-o em vez disso.

Base64 não é criptografia

Este é o ponto mais importante. A Base64 não tem chave. Qualquer um pode decifrá-lo instantaneamente, e muitas ferramentas o fazem automaticamente. No entanto, é comum encontrar:

  • Chaves de API "escondidas" na Base64 no código front-end.
  • As senhas armazenadas com código Base64 em bancos de dados ou arquivos de configuração.
  • Os segredos Kubernetes são considerados protegidos porque seus valores são Base64.

Kubernetes codifica valores secretos na Base64 puramente para que os dados binários se encaixem na YAML; a proteção vem do controle de acesso e da criptografia em repouso, que devem ser configurados separadamente. Se os dados precisarem ser confidenciais, criptografe-os com um algoritmo real, como AES-GCM, e se você precisar verificar senhas, use uma função de hash de senha não Base64 e não um hash simples como MD5 ((/blog/md5-vs-sha256)).

Casos de uso comuns bem feitos

  • ** A autenticação básica HTTP** envia Authorization: Basic base64(user:password). A codificação apenas evita problemas com caracteres especiais; as credenciais são protegidas exclusivamente pelo HTTPS.
  • ** Anexos de e-mail** utilizam MIME Base64 com intervalos de linha a cada 76 caracteres.
  • A incorporação de dados binários em JSON, como uma pequena imagem de assinatura ou uma chave criptográfica, é uma utilização legítima. Para arquivos grandes, faça upload separadamente e faça referência por URL.
  • ** Armazenamento binário em configuração de somente texto**, como certificados TLS em variáveis de ambiente.

Resolução de erros de decodificação

  • Caracter não válido: provavelmente você está decodificando Base64URL com um decodificador padrão, ou a cadeia contém espaços em branco ou intervalos de linha.
  • Enchimento incorreto: adicionar = até que o comprimento seja múltiplo de quatro.
  • Texto distorcido após decodificação: o original foi codificado a partir de um conjunto de caracteres diferente, ou os dados são binários em vez de texto.
  • ** A saída parece Base64 novamente:** os dados foram codificados duas vezes; decodificar mais uma vez.

Codificações relacionadas

  • Base32 usa 32 caracteres (AZ e 27), é insensible a maiúsculas e minúsculas e é usado em segredos TOTP para aplicativos de autenticação. As despesas gerais são 60%.
  • Hexadecimal (Base16) usa dois caracteres por byte 100% overhead mas é fácil de ler e comum para hashes.
  • Base58 remove caracteres semelhantes e é usado em endereços Bitcoin.
  • % de codificação escapa apenas caracteres inseguros em URLs.

Resumo

Base64 converte bytes para um alfabeto de texto de 64 caracteres, 3 bytes de cada vez, a um custo de cerca de 33% de tamanho extra. Use-o para transportar dados binários através de canais de texto; use a variante URL-safe em URLs e tokens; sempre converta o texto em bytes UTF-8 primeiro. Nunca o use para proteger segredos é uma codificação, não uma fechadura.

Esta página foi traduzida automaticamente do inglês. Se encontrar um erro, avise-nos.

Guias relacionados