← Todos os artigos

Base64 não é criptografia: um equívoco comum entre desenvolvedores

Strings codificadas em Base64 parecem embaralhadas, mas qualquer um decodifica com uma chamada de função. Aprenda o que Base64 realmente é, por que é confundido com criptografia e o que usar quando você precisa mesmo proteger dados.

„Vou codificar em Base64 para que ninguém leia.“ Esta frase aparece em revisões de código, mensagens de Slack e respostas do Stack Overflow muito mais do que deveria. Base64 não é criptografia. Não é obfuscação. Não é segurança de espécie alguma. Decodificá-lo exige uma chamada de função e zero conhecimento de qualquer chave ou segredo. Este artigo explica o que Base64 realmente é, por que a confusão persiste e o que usar no lugar quando você de fato precisa proteger dados.

O que é Base64 de verdade

Base64 é um esquema de codificação —— um mapeamento reversível entre dados binários e um conjunto de 64 caracteres ASCII imprimíveis (A–Z, a–z, 0–9, +, /, com = como padding).

Cada 3 bytes de entrada viram 4 caracteres Base64. O algoritmo é totalmente determinístico e não exige chave:

// Codificação
btoa("hello")          // → "aGVsbG8="
btoa("secret password") // → "c2VjcmV0IHBhc3N3b3Jk"

// Decodificação —— uma chamada, sem chave
atob("c2VjcmV0IHBhc3N3b3Jk") // → "secret password"

É tudo. Qualquer um com acesso à string codificada pode decodificá-la instantaneamente, em qualquer linguagem, em qualquer ambiente, sem informação adicional.

Por que a confusão existe

Strings codificadas em Base64 parecem dados criptografados. Estão cheias de maiúsculas, minúsculas, números e caracteres especiais misturados, e não têm semelhança visível com a entrada original. Esse ruído visual basta para enganar um observador não técnico —— e, surpreendentemente, muitas vezes também um técnico.

O padrão também é reforçado por proximidade. Base64 aparece o tempo todo em contextos de segurança:

  • Certificados HTTPS são codificados em Base64 (formato PEM)
  • Tokens JWT usam codificação Base64url para header e payload
  • A autenticação HTTP Basic envia credenciais como Base64
  • Chaves SSH são armazenadas como Base64
  • Dados criptografados costumam ser codificados em Base64 para transporte

Ver Base64 em todos esses lugares adjacentes à segurança leva os desenvolvedores a confundir codificação com segurança. A codificação é só o invólucro; a segurança vem das operações criptográficas que estão abaixo.

Codificação vs criptografia: a diferença central

A distinção é simples e absoluta:

Codificação (Base64)Criptografia (AES, RSA…)
PropósitoRepresentar dados binários como textoOcultar dados de partes não autorizadas
Precisa de chave?NãoSim
Reversível por qualquer um?Sim —— uma chamada de funçãoApenas com a chave certa
Adiciona confidencialidade?NãoSim (se usada corretamente)
Tamanho de saída~33% maior que a entradaVaria conforme o algoritmo

A criptografia transforma dados com uma chave de modo que, sem ela, recuperar o original seja computacionalmente inviável. A codificação Base64 não tem essa propriedade.

Erros de segurança do mundo real

Guardar segredos „codificados“ no código-fonte

// ❌ Isto não é secreto —— qualquer um pode decodificar
const API_KEY = atob("c2stbGl2ZS1hYmMxMjM0NTY3ODk=");

// Qualquer um que leia este código executa:
atob("c2stbGl2ZS1hYmMxMjM0NTY3ODk=") // → "sk-live-abc123456789"

Ferramentas automáticas de varredura de segredos (Secret Scanning do GitHub, GitGuardian, truffleHog) decodificam strings Base64 como parte da detecção. Se você espera que Base64 as detenha, não vai.

Autenticação HTTP Basic

// O cabeçalho Authorization fica assim:
Authorization: Basic dXNlcjpwYXNzd29yZA==

// Esse Base64 decodifica trivialmente:
atob("dXNlcjpwYXNzd29yZA==") // → "user:password"

Autenticação HTTP Basic só é segura sobre HTTPS —— a camada TLS fornece a criptografia real. O Base64 no cabeçalho é puramente para codificar o par username:password como um único valor textual, não para escondê-lo. Sobre HTTP puro, qualquer um que intercepte o tráfego lê as credenciais instantaneamente.

Tratar „tokens“ JWT como segredos

// Um JWT parece três seções Base64url unidas por pontos:
eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjQyfQ.abc123

// A seção do meio (payload) decodifica para:
atob("eyJ1c2VySWQiOjQyfQ") // → '{"userId":42}'

Payloads JWT não são criptografados —— são codificados em Base64url e assinados. Qualquer um que receba o token pode ler o payload. A assinatura impede adulteração, mas não fornece confidencialidade. Nunca coloque dados sensíveis (senhas, números de cartão, informações pessoais) em um payload JWT a menos que use JWE (JSON Web Encryption), que é um padrão diferente e bem menos comum.

Obfuscar dados em URLs

// Padrão comum em apps legados
/profile?data=eyJ1c2VySWQiOjQyfQ==

// Cole isto em qualquer decodificador:
atob("eyJ1c2VySWQiOjQyfQ==") // → '{"userId":42}'

Base64 em URLs não acrescenta segurança alguma. Também quebra facilmente —— os caracteres + e / do Base64 padrão não são URL-safe e precisam ser percent-encoded, por isso o Base64url (+-, /_, sem padding) existe como variante separada.

Para que Base64 serve de verdade

Base64 tem usos legítimos e importantes —— só que não para segurança:

  • Embutir dados binários em formatos de texto —— imagens, fontes e arquivos embutidos como URIs data: em HTML/CSS ou anexos em respostas JSON de API
  • Anexos de e-mail —— a codificação MIME usa Base64 para transmitir arquivos binários por protocolos que só lidam com ASCII de 7 bits
  • Segurança de transporte —— alguns canais corrompem dados binários (bytes nulos, caracteres de controle); Base64 garante que o conteúdo chegue intacto
  • Identificadores opacos —— codificar um ID ou cursor como Base64 sinaliza aos consumidores da API „não tente parsear isto“, embora não traga segurança

O que usar quando você realmente precisa de segurança

Se seu objetivo é impedir acesso não autorizado a dados, use uma ferramenta criptográfica de verdade:

ObjetivoO que usar
Criptografar dados em repousoAES-256-GCM (criptografia simétrica)
Criptografar dados em trânsitoTLS 1.3 (HTTPS)
Hash de senhasbcrypt, scrypt ou Argon2 —— nunca SHA-256 sozinho
Assinar tokensHMAC-SHA256 (como JWT HS256) ou RS256
Armazenar segredosVariáveis de ambiente, um gerenciador de segredos (Vault, AWS Secrets Manager)
Criptografar tokens fim-a-fimJWE (JSON Web Encryption) —— não JWT puro

Quando você realmente precisa de um token criptografado: JWE e JOSE

Um JWT padrão é assinado (JWS), não criptografado —— o payload pode ser lido. Se você precisa de confidencialidade dos claims, use um JWE (JSON Web Encryption, RFC 7516). JWE faz parte da família de padrões JOSE:

  • Algoritmos JOSE —— criptografia de conteúdo (ex.: A256GCM) e gestão de chaves (ex.: RSA-OAEP-256, ECDH-ES, A256KW). „alg“ escolhe como a chave de criptografia de conteúdo é empacotada; „enc“ escolhe como o payload é criptografado.
  • Wrapping de chave —— JWE gera uma chave de criptografia de conteúdo nova por mensagem e a envolve sob a chave do destinatário (assimétrica ou simétrica). A chave embrulhada viaja no cabeçalho do token. Isso permite criptografar o mesmo texto claro para diferentes destinatários sem recriptografar o corpo.
  • Forma compacta do JWE —— cinco seções Base64url unidas por pontos (header.key.iv.ciphertext.tag), visualmente parecido com um JWT, mas com quatro pedaços em vez de três.

Escolha uma biblioteca revisada (jose, node-jose, python-jose) em vez de implementar JWE por conta própria —— as combinações de algoritmos e formatos de chave são sutis, e o downgrade silencioso para algoritmos fracos é um bug clássico do JOSE.

Um teste rápido para o seu próprio código

Pesquise na sua base de código por btoa(, atob( e Buffer.from(…, 'base64'). Para cada ocorrência, pergunte:

  • Faço isso para o texto caber em um campo ou sobreviver ao transporte? → Bom.
  • Faço isso para esconder dados de alguém? → Substitua por criptografia real ou controle de acesso.

Perguntas frequentes

Base64 é criptografia?

Não. Base64 é uma codificação reversível sem chave —— qualquer um pode decodificar em uma chamada (atob()). Criptografia exige uma chave e torna inviável recuperar o conteúdo sem ela.

É seguro guardar senhas ou chaves de API em Base64?

Não. A decodificação é trivial e scanners de segredos decodificam Base64 automaticamente. Use um gerenciador de segredos ou variáveis de ambiente e hashee senhas com bcrypt, scrypt ou Argon2.

Qualquer um pode ler o payload de um JWT?

Sim. Payloads JWT são codificados em Base64url e assinados, não criptografados —— qualquer um com o token pode ler todas as claims. Nunca coloque segredos em um JWT a menos que use JWE. Colar tokens em ferramentas online é arriscado; veja por que você não deve colar JSON sensível online.

Para que serve Base64 então?

Representar dados binários como texto de forma segura —— URIs data:, anexos de e-mail (MIME) e transporte por canais que só lidam com ASCII. É um invólucro, não uma medida de segurança.

Codifique e decodifique no seu navegador

Precisa inspecionar uma string Base64 agora? Codificação e decodificação Base64 no fixjson.org permite codificar ou decodificar qualquer string instantaneamente —— incluindo Unicode completo e UTF-8 —— sem instalar nada. Útil para depurar payloads JWT, inspecionar respostas de API ou ver o que se esconde dentro de uma URI data:.