Por que embrulhar binário em texto
Muitos meios de transporte foram feitos para texto, não para bytes brutos: corpos de e-mail, documentos JSON e XML, cabeçalhos HTTP, arquivos-fonte. Coloque binário bruto em qualquer um deles e um byte de controle ou nulo perdido pode quebrar a análise. O Base64 resolve isso reexpressando os bytes usando apenas caracteres imprimíveis seguros, de modo que o binário possa trafegar dentro de um canal somente texto intacto. Eis onde isso realmente acontece.
Os cenários comuns
- Data URIs. Uma URL
data:incorpora um pequeno recurso diretamente na marcação ou no CSS, por exemplodata:image/png;base64,iVBORw0KGgo.... Os bytes da imagem ficam em Base64 ali mesmo no atributo, poupando uma requisição de rede separada para recursos minúsculos. - E-mail (). Anexos e corpos não-ASCII são transportados com
Content-Transfer-Encoding: base64. O MIME quebra a saída em linhas (classicamente de 76 caracteres) para que servidores de correio antigos não engasguem com linhas longas. - . Certificados e chaves são bytes embrulhados em Base64 entre os marcadores
-----BEGIN CERTIFICATE-----e-----END CERTIFICATE-----, com linhas quebradas em 64 caracteres. O PEM é o motivo pelo qual um certificado é um bloco de texto que você pode colar em um arquivo de configuração. - Autenticação HTTP Basic. O cabeçalho
Authorization: Basicé o Base64 deusuário:senha.
O custo de tamanho
O Base64 não é de graça. Três bytes viram quatro caracteres, então a forma codificada é cerca de 33% maior que a original, antes de qualquer sobrecarga de quebra de linha. Essa troca geralmente vale a pena pela correção em um canal de texto, mas é o motivo pelo qual você não codificaria em Base64 um arquivo grande que poderia enviar como bytes brutos. Para pequenos recursos embutidos, a conveniência vence; para cargas grandes, a sobrecarga favorece um transporte binário.
Codificação não é criptografia
O exemplo do Basic auth já deixa o ponto mais importante claro. Authorization: Basic dXNlcjpwYXNz parece opaco, mas dXNlcjpwYXNz é simplesmente o Base64 de user:pass, reversível por qualquer pessoa, sem nenhuma chave envolvida. O Base64 não oferece nenhuma confidencialidade. É uma codificação (uma mudança reversível de representação), não criptografia (um segredo protegido por chave) e nem hashing (uma impressão digital de mão única). É por isso que o Basic auth só é seguro sobre TLS: o transporte criptografa o cabeçalho, porque o Base64 certamente não o faz.
Sempre que você vir uma string longa de aparência opaca, decodificá-la primeiro é uma forma barata de descobrir o que ela é. A ferramenta Base64 decodifica data URIs, corpos PEM e cabeçalhos de autenticação para seus bytes e texto brutos, inteiramente no seu navegador, então nada do que você cola sai da página.
Codificações empilhadas: dupla, tripla e além
Como a codificação é reversível e não carrega nenhuma chave, é trivial aplicá-la mais de uma vez. Faça o Base64 da saída de um Base64 e você tem uma string duplamente codificada; repita para obter uma tripla. Cada passagem é legítima por si só, e o resultado ainda é apenas texto, que é exatamente por que é um recurso de ofuscação predileto. Atacantes empilham codificações (às vezes misturando Base64, URL/percent e hexadecimal entre as camadas) para que uma carga passe por um filtro ou uma assinatura que só inspeciona a forma mais externa, ou a primeira decodificada. Uma regra de (firewall de aplicação web, do inglês web application firewall) que casa com <script nunca a vê se a requisição carrega PHNjcmlwdA== embrulhado mais uma vez.
A defesa é simétrica: para entender um blob suspeito, você descasca as camadas, decodificando repetidamente até chegar a um texto plausível em vez de mais uma string codificada. O sinal de que você ainda não terminou é que uma decodificação produz algo que continua parecendo codificado (todo o alfabeto Base64, ou cheio de escapes %). Um hábito prático é continuar decodificando até a saída parar de mudar de forma.
A ferramenta Base64 apoia isso diretamente: o controle de camadas (×1, ×2, ×3) codifica uma carga em várias passagens, ou remove várias ao decodificar. Se você pedir para remover mais camadas do que uma carga realmente tem, ela para na primeira camada que falha ao decodificar e mostra exatamente onde, para você ver quão profundo o aninhamento realmente foi. É a mesma razão pela qual ferramentas de segurança que normalizam a entrada decodificam recursivamente antes de casar: uma regra que inspeciona apenas uma camada é uma regra que um base64 a mais derrota.