Base64 é a operação pseudo-segura que mais vi ser mal usada. Um dev de backend anuncia orgulhoso criptografei este token com Base64; o dev de frontend assente educadamente e depois reverte em uma linha.

Este artigo existe para que da próxima vez que você ler Base64 criptografado possa dizer imediatamente—isso não é criptografia.

Resumo de 30 segundos

  • Base64 é codificação, não criptografia. Mapeia dados binários para 64 caracteres imprimíveis. Qualquer pessoa que veja a string pode revertê-la para os bytes originais.
  • Uma linha para reverter: Buffer.from(str, ‘base64’).toString() em Node.js, atob(str) no navegador. Pronto.
  • O trabalho real dela: deixar dados binários viajarem por canais que aceitam só texto—JSON, corpos de e-mail, query strings de URL.
  • Não serve para esconder senhas, tokens ou chaves de API. Para isso você precisa de criptografia real: AES, libsodium, age, GPG.

5 cenários reais onde Base64 está errado

Cenário 1: criptografar senhas em arquivos de configuração

db_password=cm9vdC1wYXNzLXdvcmQ=

Acredite ou não, essa string decodifica para root-pass-word.

Por que times caem nisso: arquivos de configuração são o ativo mais vazado em qualquer repositório. Base64 parece adicionar uma senha, mas qualquer pessoa com o arquivo reverte em 5 segundos.

A correção: use SOPS, age, Vault, ou no mínimo AES-GCM. Base64 é mascaramento, não criptografia.

Cenário 2: JWT criptografa o payload

eyJhbG…lKxw

O trecho do meio normalmente é Base64URL. Jogue em qualquer decodificador JWT online—ID do usuário, expiração, escopos estão todos lá.

Por que times caem nisso: assinaturas JWT enganam as pessoas fazendo pensar invisível = seguro. O payload nunca é criptografado; está explícito na especificação JWT—assinado, não criptografado. Se você quer o payload criptografado, use JWE.

Cenário 3: criptografe sua chave de API na documentação

Authorization: Basic YWRtaW46cGFzc3dvcmQ=

Decodifica para admin:password.

Por que times caem nisso: Authorization: Basic … aparece em tutoriais por toda parte; novatos copiam sem perceber que o trecho depois de Basic é apenas username:password em texto plano codificado em Base64.

Cenário 4: escondendo IDs sensíveis em URLs

/users/details?token=MTIzNDU2Nzg5MDEyMzQ1Ng==

Envolva um ID interno em Base64, coloque na URL, espere que ninguém adivinhe a chave primária correspondente.

Por que times caem nisso: isso é obscuridade por codificação. Strings Base64 parecem hash ou cifrado, mas IDs geralmente são inteiros sequenciais, e Base64 só adiciona uma camada de adivinhação, não segurança. Alguém percorrendo IDs em ordem percorre a forma codificada em ordem também.

Cenário 5: colando trechos de código criptografados no Slack ou e-mail

Alguém cola: descriptografe isso antes de prod, o segredo está em base64 Resposta: o quê? Remetente: eu, o original era secret_api_key_here_in_plain

Eu juro por projetos falhados que esse cenário existe.

Por que times caem nisso: assumindo que Base64 escapa de busca, cópia, screenshot ou OCR. Não escapa—strings Base64 têm aparência distinta e são exatamente o que ferramentas automatizadas de auditoria de tráfego procuram.

4 fatos contraintuitivos sobre Base64

Fato 1: strings Base64 são 33% mais longas que o original

A codificação aumenta os dados. 3 bytes viram 4 caracteres Base64, então aGVsbG8= é mais longo que hello. Se você está chamando sua codificação de criptografia e reclamando que a saída ficou mais longa, escolheu a ferramenta errada.

Fato 2: Base64 não é hash

Hashes são de ida (teoricamente irreversíveis), Base64 é de ida e volta (totalmente reversível). São ferramentas diferentes para trabalhos diferentes. Qualquer um que use Base64 para fazer hash de senhas e as guarde no banco de dados não guardou hash nenhum—qualquer atacante decodifica direto.

Fato 3: Base64 não é compressão

É só uma troca de conjunto de caracteres. Nenhum dado é removido. aGVsbG8= sempre ocupa ≥ os bytes de hello + padding.

Fato 4: o btoa do navegador só suporta Latin-1

Chamar btoa(‘你好’) lança InvalidCharacterError porque btoa só codifica pontos de código 0–255. Por isso nossa ferramenta Text Encoder faz TextEncoder().encode() depois btoa depois TextDecoder().decode(), para ser UTF-8 safe de ponta a ponta.

Práticas recomendadas

  1. Proteger senhas / tokens / chaves de API: use criptografia real. AES-256-GCM, libsodium (crypto_secretbox_easy), age, GPG—escolha um, nunca Base64.
  2. Botar binário em JSON ou URLs: use Base64, esse é o trabalho dela. A aba Base64 da nossa ferramenta Text Encoder usa por padrão a cadeia UTF-8 safe, decodifique aGVsbG8= e veja hello.
  3. Transporte binário URL-safe: use Base64URL (- e _ no lugar de + e /, sem padding). Combina com JWT.
  4. Incorporar imagens em HTML/CSS: use data:image/…;base64,…—mas o HTML fica +33% maior e não pode ser cacheado por CDN, então use com moderação.
  5. Ensinar Base64 para iniciantes: reforce isso é um caminhão de mudança, não um cofre. Caminhões mudam móveis de A até B e qualquer transportadora pode ver o conteúdo; cofres (Fort Knox) são o que você quer para confidencialidade real.

Base64 é, por especificação, um esquema de codificação de caracteres (RFC 4648)—apenas transporte. Escrever hello depois مرحبا depois hello de novo é puro movimento sem significado de segurança. Se você precisa de segurança, precisa de primitivas criptográficas reais.

Experimente nossa ferramenta Text Encoder, vá para a aba Base64, cole qualquer string e codifique/decodifique na hora—veja a diferença entre codificação e criptografia em um segundo. Se quiser comparar contra hashes (HMAC, SHA-256), veja nosso crypto-tools.