A diferença entre base64url e base64 se resume a três pequenas alterações: o base64 padrão usa + e / em seu alfabeto, além do preenchimento com =, enquanto o base64url troca + por -, troca / por _ e geralmente remove o preenchimento com = por completo. Essa é toda a diferença no nível da especificação. Todo o resto, a matemática de codificação, o agrupamento de 6 bits, a sobrecarga de tamanho de 33%, é idêntico entre os dois.
Por que isso importa? Porque +, / e = têm significados reservados dentro de URLs, strings de consulta e nomes de arquivos. Coloque uma string base64 padrão em uma URL e + pode ser interpretado como um espaço, / inicia um novo segmento de caminho e = parece uma atribuição de parâmetro. O base64url existe para que os dados codificados sobrevivam a esses contextos intactos. Este guia aborda exatamente quando cada variante é necessária, o problema do re-preenchimento que a maioria dos artigos ignora e por que os JSON Web Tokens usam base64url para seu cabeçalho e payload.
Base64url vs Base64: A Diferença Essencial#
Ambas as variantes são definidas na RFC 4648. O base64 padrão está na Seção 4; o alfabeto seguro para URL e nome de arquivo está na Seção 5. Elas codificam bytes da mesma forma: pegam três bytes (24 bits), dividem em quatro grupos de 6 bits e mapeiam cada grupo para um caractere de um alfabeto de 64 caracteres. A única coisa que muda são quais caracteres preenchem os dois últimos slots desse alfabeto e se você usa padding no final.
Aqui está a comparação lado a lado que realmente importa:
| Aspecto | Base64 padrão | Base64url |
|---|---|---|
| Caractere do índice 62 | + (mais) | - (hífen/traço) |
| Caractere do índice 63 | / (barra) | _ (sublinhado) |
| Padding | = para múltiplo de 4 | Geralmente omitido |
| Seguro em URLs / query strings | Não | Sim |
| Seguro em nomes de arquivo | Não (a / quebra caminhos) | Sim |
| Seção da RFC 4648 | Seção 4 | Seção 5 |
| Tamanho da saída | Idêntico | Idêntico |
Observe que os primeiros 62 caracteres (A-Z, a-z, 0-9) são os mesmos em ambos os alfabetos. Apenas as posições 62 e 63 diferem. É por isso que converter entre os dois é uma substituição trivial de caracteres e nunca requer recodificação dos bytes originais.
Dica rápida: se você vir uma string com aparência de base64 contendo
-ou_, provavelmente está vendo base64url. O base64 padrão nunca usa esses dois caracteres.
Por que + e / quebram dentro de URLs#
Uma URL tem uma gramática, e vários caracteres carregam significado estrutural. A barra / separa segmentos de caminho. O sinal de mais + é historicamente interpretado como um espaço codificado em dados application/x-www-form-urlencoded (o formato usado por query strings e envios de formulários). O sinal de igual = separa o nome de um parâmetro de consulta do seu valor.
Então, se você colocar um token base64 padrão como a+b/c= diretamente em uma URL, um servidor pode decodificar o + como um espaço, tratar /c como um novo caminho e ler = como o início de um valor. Seus dados serão corrompidos antes mesmo de seu código tocá-los. O base64url contorna todo o problema nunca emitindo nenhum desses três caracteres.
Quando Você Deve Usar Cada Variante#
A regra de decisão é curta. Use base64url sempre que a saída trafegar por uma URL, um parâmetro de consulta, um cabeçalho HTTP, um nome de arquivo ou um cookie. Use base64 padrão para todo o resto: anexos de e-mail (MIME), URIs de dados, arquivos de configuração, valores de string JSON que não estão vinculados a URLs e blobs binários armazenados em um banco de dados.
Use base64url quando o valor codificado aparecer em:
- Um caminho de URL ou string de consulta (por exemplo
?token=...) - Um JWT (cabeçalho, payload e assinatura são todos base64url)
- Um parâmetro OAuth ou OpenID Connect como
stateoucode_challenge - Um nome de arquivo ou chave de objeto S3 (a
/no base64 padrão criaria pastas não intencionais) - Chaves WebPush, credenciais FIDO/WebAuthn e muitos outros contextos de criptografia web
Use base64 padrão quando o valor viver em:
- Um anexo de e-mail codificado como MIME
- Uma URI
data:incorporada em HTML ou CSS (estes toleram+e/sem problemas) - Um valor de configuração JSON ou YAML que nunca é colocado em uma URL
- Uma coluna de banco de dados ou linha de log
Se você não tiver certeza de qual variante está usando, cole-a no codificador e decodificador base64 gratuito e decodifique-a de ambas as formas. Se apenas uma variante produzir saída limpa e legível, isso indica qual alfabeto a produziu.
A Pegadinha do Padding que a Maioria dos Guias Ignora#
Esta é a parte que confunde as pessoas e o motivo pelo qual um trecho copiado às vezes gera um erro. O base64 padrão preenche a saída com = para que o comprimento total seja sempre um múltiplo de 4. O Base64url normalmente remove esse preenchimento porque = também não é seguro em URLs.
A matemática: o base64 codifica 3 bytes em 4 caracteres. Quando sua entrada não é um múltiplo de 3 bytes, o codificador preenche a lacuna com =. Um byte restante produz dois caracteres de preenchimento (==), dois bytes restantes produzem um (=).
Aqui está a armadilha. Muitos decodificadores rigorosos exigem um comprimento que seja múltiplo de 4. Quando o base64url remove o preenchimento, o comprimento da string não é mais um múltiplo de 4, então um decodificador ingênuo falha. A solução é readicionar o preenchimento antes de decodificar.
Como readicionar o preenchimento ao base64url antes de decodificar#
Para decodificar com segurança uma string base64url com um decodificador base64 genérico, faça duas coisas: converta o alfabeto de volta (- para +, _ para /), depois adicione = até que o comprimento seja um múltiplo de 4.
Em JavaScript:
function base64urlDecode(input) {
// 1. Restaurar o alfabeto padrão
let b64 = input.replace(/-/g, '+').replace(/_/g, '/');
// 2. Readicionar preenchimento para múltiplo de 4
const pad = b64.length % 4;
if (pad === 2) b64 += '==';
else if (pad === 3) b64 += '=';
else if (pad === 1) throw new Error('Comprimento base64url inválido');
return atob(b64);
}
Um resto de comprimento 1 é impossível em base64 válido, então trate como uma entrada malformada em vez de adivinhar. Se você pular a etapa de readicionar o preenchimento, atob e a maioria dos decodificadores do lado do servidor rejeitarão a string ou retornarão lixo. Nosso codec base64 lida com o re-preenchimento automaticamente, então você pode inserir um token base64url sem preenchimento e ele decodifica sem você fazer a aritmética.
Por que JWTs usam Base64url (e não Base64)#
Um JSON Web Token é composto por três segmentos em base64url separados por pontos: header.payload.signature. A razão para usar base64url em vez do base64 padrão é exatamente o problema mencionado acima. Tokens são passados em URLs, em cabeçalhos Authorization: Bearer e em parâmetros de consulta durante fluxos OAuth. Um token base64 padrão com / ou + quebraria no momento em que fosse usado em uma URL.
Portanto, a especificação JWT (RFC 7519, baseada na RFC 7515) determina o uso de base64url sem padding. É por isso que um JWT nunca contém =, + ou /, apenas letras, dígitos, hífens, underscores e os dois pontos separadores.
Aviso: base64url é codificação, não criptografia. Qualquer pessoa pode decodificar o payload de um JWT e ler suas claims. Nunca coloque segredos no corpo de um JWT. A assinatura prova que o token não foi adulterado, mas não oculta o conteúdo.
Se você quiser inspecionar um token, pode separar os três segmentos e decodificar o header e o payload em base64url com a ferramenta de decodificação JWT. Ela faz a conversão do alfabeto e o re-padding para que você veja as claims JSON brutas instantaneamente. Para entender o que o segmento de assinatura prova em comparação com o que apenas a decodificação mostra, vale a pena ler a análise em decodificar vs verificar um JWT antes de confiar em qualquer token em produção.
Convertendo entre as duas variantes#
Como apenas dois caracteres e o preenchimento diferem, a conversão é pura manipulação de strings. Você nunca executa novamente o algoritmo base64.
Base64 padrão para base64url:
- Substitua cada
+por- - Substitua cada
/por_ - Remova os caracteres
=finais
Base64url de volta para base64 padrão:
- Substitua cada
-por+ - Substitua cada
_por/ - Adicione preenchimento
=até que o comprimento seja múltiplo de 4
Essa simetria é a conclusão prática: os dois formatos são os mesmos dados com roupas diferentes. Se uma decodificação falhar, a causa é quase sempre uma incompatibilidade (você inseriu base64url em um decodificador padrão sem converter) ou preenchimento ausente, não dados corrompidos.
Um exemplo prático#
Pegue os bytes da string Hello?>. O base64 padrão codifica para SGVsbG8/Pg==. Observe o / no índice 8 e o preenchimento ==. Como base64url, os mesmos bytes se tornam SGVsbG8_Pg: o / agora é _ e o preenchimento desapareceu. Decodifique qualquer um e você obtém Hello?> de volta. Mesmo conteúdo, duas representações seguras para contextos diferentes.
Erros Comuns e Como Evitá-los#
Alguns erros aparecem repetidamente quando desenvolvedores misturam as duas variantes:
- Decodificar base64url com um decodificador padrão e obter um erro. Converta
-/_de volta e adicione o preenchimento primeiro. Esta é a falha mais comum. - Supor que
=está sempre presente. Código que divide ou valida com base no comprimento do preenchimento quebra ao encontrar base64url sem preenchimento. Torne o preenchimento opcional na sua análise. - Codificar uma string base64 padrão para URL em vez de usar base64url. Isso funciona, mas incha a saída:
+vira%2B,/vira%2F. Base64url é mais curto e limpo para contextos de URL. - Tratar base64 ou base64url como uma camada de segurança. Ambos são reversíveis por qualquer pessoa. Use-os para transportar binários como texto, nunca para proteger dados.
- Esquecer que ambos os formatos têm a mesma sobrecarga de 33% no tamanho. Codificar 3 bytes como 4 caracteres significa que sua saída é cerca de um terço maior que a entrada bruta, em qualquer variante.
Se você está lidando com binários codificados, como imagens junto com texto, o guia sobre como codificar e decodificar imagens base64 e URLs de dados cobre o lado das URIs de dados, onde base64 padrão é a escolha certa.
Perguntas Frequentes#
Base64url é igual ao base64?
Não, mas são próximos. O base64url usa exatamente o mesmo algoritmo de codificação e produz a mesma saída em comprimento. As únicas diferenças são que + vira -, / vira _, e o preenchimento = geralmente é removido para que a string seja segura para uso em URLs e nomes de arquivos.
Por que o base64url remove o preenchimento?
O caractere de preenchimento = tem um significado reservado em URLs (ele separa o nome de um parâmetro de consulta do seu valor), então mantê-lo poderia corromper os dados ou confundir um servidor. O base64url o remove por segurança. A desvantagem é que decodificadores rigorosos podem exigir que você readicione o preenchimento antes de decodificar.
Posso decodificar base64url com um decodificador base64 normal?
Sim, mas apenas após duas etapas. Primeiro, converta o alfabeto de volta substituindo - por + e _ por /. Depois, readicione o preenchimento com = até que o comprimento da string seja múltiplo de 4. Pule qualquer uma das etapas e a maioria dos decodificadores padrão lançará um erro ou retornará lixo.
Por que os JWTs usam base64url em vez de base64 padrão?
Porque os tokens trafegam por URLs, cabeçalhos HTTP e parâmetros OAuth onde +, / e = quebrariam. A especificação JWT exige base64url sem preenchimento, e é por isso que você nunca vê esses três caracteres em um JSON Web Token válido, apenas letras, dígitos, hífens, underscores e separadores de ponto.
Base64url é criptografia ou apenas codificação? É apenas codificação. Qualquer um pode reverter sem chave, exatamente como o base64 padrão. Ele existe para representar dados binários como texto seguro para URL, não para manter algo secreto. Nunca armazene senhas, chaves de API ou outros dados sensíveis como base64url e presuma que estão protegidos.
Base64url produz uma string menor que o base64?
Ligeiramente, apenas porque geralmente omite o preenchimento = (economizando zero a dois caracteres). O corpo codificado tem o mesmo comprimento em ambos. Ambas as variantes adicionam aproximadamente a mesma sobrecarga de 33% em relação ao binário bruto, já que cada 3 bytes se tornam 4 caracteres.
Base64url vs base64 não é um mistério profundo quando você vê como um alfabeto com dois caracteres trocados e preenchimento opcional. Recorra ao base64url sempre que seus dados tocarem uma URL, cabeçalho, nome de arquivo ou JWT, e ao base64 padrão para MIME, data URIs e armazenamento. Quando uma decodificação falhar, suspeite primeiro de uma incompatibilidade de variante ou preenchimento ausente, depois jogue a string no codificador e decodificador base64 para confirmar qual alfabeto você está segurando.



