Pular para o conteúdo
LeedyBox
Apoiar

Base64, codificação de URL e JWT explicados

Esses três aparecem sempre que dados precisam viajar como texto: em URLs, cabeçalhos HTTP, JSON e tokens de login. Nenhum deles esconde nada. Este guia explica como cada um funciona, onde você vai encontrá-los e os erros por trás da maioria dos problemas.

Codificar não é criptografar

Codificar muda a forma como os dados são escritos para que atravessem um canal que só aceita certos caracteres. Qualquer pessoa pode desfazer isso, porque nenhuma chave está envolvida. A criptografia também altera os dados, mas só quem tem a chave consegue revertê-los. Um hash é outra coisa: uma impressão digital de mão única que não pode ser revertida, como explica Funções hash explicadas.

Base64 e codificação de URL são codificações. Um JWT costuma ser assinado, o que prova quem o emitiu e que não foi alterado, mas seu conteúdo é apenas codificado. Se um valor precisa permanecer secreto, ele precisa de criptografia, não de um desses formatos.

Como o Base64 funciona

O Base64 lê os dados de três em três bytes (24 bits) e os divide em quatro grupos de seis bits. Cada grupo é um número de 0 a 63, escrito como um caractere de um alfabeto de 64: A–Z para 0–25, a–z para 26–51, 0–9 para 52–61 e depois + e /. A palavra “Man” mostra os passos:

PassoMan
Valores dos bytes7797110
Bits010011010110000101101110
Quatro grupos de 6 bits010011 · 010110 · 000101 · 101110 = 19 · 22 · 5 · 46
Base64T W F u → TWFu

Quando o tamanho da entrada não é múltiplo de três, o último grupo é completado e marcado com preenchimento: um byte restante gera dois caracteres e ==, dois bytes restantes geram três caracteres e =. “Ma” vira TWE= e “M” vira TQ==.

Como cada três bytes viram quatro caracteres, o Base64 aumenta os dados em cerca de um terço, mais as quebras de linha que alguns formatos acrescentam. Uma foto de 3 MB enviada como anexo de e-mail viaja como cerca de 4 MB de texto, e uma imagem incorporada a uma folha de estilos como URL de dados fica cerca de um terço mais pesada que o arquivo.

Onde você encontra Base64

  • Anexos de e-mail (MIME) são texto Base64, quebrado em linhas de 76 caracteres.
  • URLs de dados como data:image/png;base64,iVBORw0… colocam um arquivo pequeno direto no HTML ou no CSS.
  • A autenticação HTTP básica envia user:password em Base64 no cabeçalho Authorization. Isso só esconde a senha de olhares casuais, por isso só é segura com HTTPS.
  • Certificados e chaves em arquivos PEM são Base64 entre as linhas -----BEGIN …----- e -----END …-----, quebrado a cada 64 caracteres.
  • JSON e XML carregam valores binários, como uma assinatura ou uma miniatura, em strings Base64 porque não têm tipo binário.

Base64URL e preenchimento

O + e a / do Base64 padrão têm significado em URLs e caminhos de arquivo, então um segundo alfabeto, o Base64URL, usa - e _ no lugar. Ele também costuma omitir o preenchimento =, já que o decodificador consegue calcular o tamanho. JWTs, muitos tokens de API e alguns nomes de arquivo usam Base64URL. Para transformar Base64 padrão em Base64URL, troque + por -, / por _ e remova os = finais; para voltar, desfaça as trocas e acrescente = até o tamanho ser múltiplo de quatro.

Codificação por porcentagem em URLs

Uma URL só pode conter um conjunto limitado de caracteres, e alguns deles estruturam o endereço: / e ? separam o caminho e a consulta, & e = separam parâmetros, # inicia o fragmento. Quando um valor contém um desses caracteres, ou qualquer coisa fora do ASCII, ele é codificado por porcentagem: cada byte da sua forma UTF-8 é escrito como % seguido de dois dígitos hexadecimais. “café” vira caf%C3%A9, porque é corresponde aos dois bytes C3 A9.

Letras, dígitos e - . _ ~ nunca precisam ser codificados. Estes são os caracteres que mais causam problemas:

CaractereCodificadoPor que importa
espaço%20Não é permitido em uma URL
&%26Iniciaria um novo parâmetro
=%3DEncerraria o nome do parâmetro
?%3FIniciaria a consulta
#%23Iniciaria o fragmento, que não é enviado ao servidor
/%2FAcrescentaria um segmento de caminho
+%2BÉ lido como espaço em dados de formulário
%%25Iniciaria uma sequência de escape

Codifique cada valor separadamente e depois monte a URL. Em JavaScript, encodeURIComponent faz isso para um valor e também codifica / ? & = #, enquanto encodeURI serve para um endereço inteiro e deixa esses caracteres como estão. Usar encodeURI em um único valor é uma causa comum de strings de consulta quebradas.

Sinais de mais, espaços e codificação dupla

Formulários HTML enviam seus campos como application/x-www-form-urlencoded, em que um espaço vira +. Na sintaxe geral de URLs, + é só um sinal de mais. Por isso, uma busca por “C++” enviada como q=C++ chega como “C” seguido de dois espaços a um servidor que decodifica dados de formulário; ela deveria ser enviada como q=C%2B%2B. Ao decodificar uma string de consulta à mão, descubra primeiro qual regra a gerou.

A codificação dupla acontece quando um valor já codificado é codificado de novo: %20 vira %2520, porque o próprio % vira %25. Se você vir %25 seguido de dois dígitos hexadecimais em uma URL, algo na cadeia codificou duas vezes; decodifique uma vez e procure onde está o passo a mais.

O que há dentro de um JWT

Um JSON Web Token (JWT) leva declarações (claims), como quem é o usuário e até quando o token vale, do sistema que o emite para os sistemas que o aceitam. A forma assinada comum tem três partes Base64URL separadas por pontos: um cabeçalho, uma carga útil e uma assinatura. Decodificadas, as duas primeiras são JSON comum:

Header:  {"alg": "HS256", "typ": "JWT"}
Payload: {"sub": "user-42", "role": "editor", "iat": 1767225600, "exp": 1767229200}

O padrão (RFC 7519) define algumas declarações registradas; as aplicações acrescentam as suas, como role acima.

DeclaraçãoSignificado
issEmissor: quem criou o token
subSujeito: geralmente o ID do usuário ou da conta
audPúblico: o serviço ao qual o token se destina
exp, nbf, iatExpira, não antes de, emitido em: tempo Unix em segundos
jtiID do token, usado para detectar reutilização ou revogar um token específico

Como a carga útil é apenas codificada, qualquer pessoa com o token pode lê-la. Não coloque dados pessoais nem segredos nela, e mantenha os tokens pequenos: eles viajam em cada requisição, e muitos servidores limitam o tamanho dos cabeçalhos.

Assinado não é secreto: como um JWT é verificado

A assinatura é calculada sobre o cabeçalho e a carga útil. Com HS256, emissor e receptor compartilham um segredo e usam HMAC com SHA-256. Com RS256 ou ES256, o emissor assina com uma chave privada e os receptores verificam com a chave pública correspondente, então eles não conseguem criar tokens por conta própria.

Um servidor que recebe um token precisa verificar a assinatura com o algoritmo e a chave esperados e conferir exp, nbf, iss e aud antes de confiar em qualquer declaração. Decodificar, como faz a ferramenta da LeedyBox, pula tudo isso: mostra o que o token diz, não se ele é autêntico. As bibliotecas também devem rejeitar o algoritmo “none”, que indica um token sem assinatura, a menos que tokens sem assinatura sejam esperados. Quando o próprio conteúdo precisa ficar oculto, o token é criptografado (JWE) e passa a ter cinco partes que não podem ser lidas sem a chave.

Problemas comuns e soluções

SintomaCausa provávelSolução
O Base64 decodifica em texto embaralhadoOs dados são binários ou texto em outra codificaçãoVerifique o que foi codificado; salve dados binários como arquivo
“Caractere inválido” ao decodificarUm prefixo data:, aspas ou o alfabeto Base64URLRemova tudo antes da vírgula; use um decodificador que aceite - e _
Um parâmetro chega cortadoUm & ou # não codificado no valorCodifique cada valor com encodeURIComponent
%2520 em uma URLO valor foi codificado duas vezesCodifique uma vez, no ponto em que a URL é montada
Token rejeitado embora exp esteja no futuroPúblico ou emissor errados, diferença de relógio ou chave diferenteCompare aud, iss e a chave de assinatura com o que o servidor espera
Data de expiração milhares de anos no futuroexp escrito em milissegundos em vez de segundosGuarde exp, nbf e iat em segundos

Perguntas frequentes

O Base64 serve para proteger uma senha ou chave de API?

Não. Qualquer pessoa reverte Base64 em um segundo. Uma credencial codificada em Base64, por exemplo em um arquivo de configuração ou em uma URL, fica tão exposta quanto texto puro.

Posso colocar dados pessoais na carga útil de um JWT?

Evite. Qualquer um que tenha o token pode ler a carga útil, inclusive extensões do navegador, logs e proxies que veem a requisição. Coloque um ID no token e consulte os detalhes no servidor.

A codificação de URL protege contra ataques de injeção?

Só no sentido de que um valor não consegue quebrar a estrutura da URL. O servidor ainda precisa validar e escapar o valor decodificado de acordo com o lugar onde o usa, como SQL, HTML ou um comando de shell.

Por que minha string Base64 é maior que o arquivo?

Cada três bytes viram quatro caracteres, então o texto fica cerca de 33% maior, e as quebras de linha acrescentam um pouco mais. Para arquivos grandes, enviar os bytes diretamente é mais eficiente do que usar Base64.