Español

Herramientas de desarrollo · Codificador y decodificador Base64

Base64 vs base64url: por qué un decodificador estándar rechaza - y _

· Cómo funciona

base64 codificación flujo de trabajo del desarrollador

Alfabeto base64 frente a sustituciones de URL base64
Ilustración de vector original de ToolAcre

base64url intercambia + y / por - y _ para que la salida pueda viajar en URL y nombres de archivos sin escapar. Esta publicación explica los dos alfabetos, cómo convertir entre ellos y por qué generalmente también se elimina el relleno.

El token que decodifica en todas partes excepto en su código (un error de carácter no válido causado por un solo - o _

Un segmento JWT no se puede decodificar en el decodificador Base64 estándar con un error de carácter no válido al nombrar un guión. Pero visualmente no aparece ningún guión. Mire de nuevo: así es. La versión base64url usa - donde el estándar Base64 usa + y _ donde usa /.. Muchos decodificadores aceptan solo un alfabeto, y el código que espera RFC 4648 estándar Base64 rechazará el token codificado para seguridad de URL.

Los dos alfabetos son equivalentes; la conversión entre ellos es un reemplazo mecánico de caracteres. El problema surge porque + y / tienen significados en las URL. Un signo más representa espacio en los datos del formulario application/x-www-form-urlencoded. La barra diagonal es un separador de ruta en la URL. Si incrusta Base64 directamente en el parámetro de consulta de URL sin codificación porcentual + y el decodificador /, podría malinterpretarlos.

Por qué + y / son un problema en las URL y los nombres de archivos: el significado reservado de / en las rutas y de + como espacio en los datos del formulario

A + podría leerse como un espacio antes de llegar al decodificador. Un / podría dividir el valor del parámetro en el lugar equivocado. RFC 4648 sección 5 define el alfabeto base64url para eliminar la ambigüedad: use - en lugar de + y _ en lugar de /, para que la salida sea segura en URL y nombres de archivos. Los dos alfabetos son idénticos excepto dos caracteres.

Base64 estándar utiliza caracteres en las posiciones 62 y 63: A–Z (0–25), a–z (26–51), 0–9 (52–61), + (62), / (63). base64url usa A–Z (0–25), a–z (26–51), 0–9 (52–61), - (62), _ (63). Todo lo demás (reagrupación de bits, reglas de relleno, asignación de bits a índices) es igual. La cadena de índices para Base64 estándar producirá una cadena de índices para base64url; solo los caracteres en las posiciones 62 y 63 serán diferentes.

El alfabeto base64url de la sección 4648 del RFC 5: los dos caracteres sustituidos y por qué nada más cambia

Si la entrada no contiene índices 62 o 63 (no + o / en estándar, no - o _ en base64url), ambos alfabetos producen una salida idéntica. Convertir Base64 estándar a base64url es sencillo de buscar y reemplazar: intercambiar + por - y / por _. La decodificación de la cadena base64url en Base64 estándar requiere revertir: intercambiar - por + y _ por /.

La conversión es simétrica y siempre válida. Si encuentra un token que falla en la decodificación con un nombre de error de carácter no válido, o _, verifique si el decodificador acepta base64url. De lo contrario, aplique la sustitución de caracteres y, si la entrada está bien formada, la decodificación debería realizarse correctamente. Considere el encabezado JWT {"alg":"HS256","typ":"JWT"} codificado como base64url. Los UTF-8 bytes estándar pasan por una reagrupación de bits: tres bytes se convierten en cuatro índices, buscados en el alfabeto base64url. ToolAcre expone el relleno como una opción del codificador en lugar de vincularlo al cambio alfabético. Esa separación es una evidencia útil: la salida segura para URL se puede rellenar o no, mientras que el decodificador normaliza cualquiera de las formas antes de llamar al navegador primitivo. El alfabeto y el relleno son convenciones relacionadas, no un solo cambio.

El relleno en base64url es opcional por convención: por qué los JWT omiten = y cómo un decodificador puede restaurarlo a partir de la longitud

Cuando el índice es 62, el carácter de salida es -; cuando 63, la salida es _. Bytes idénticos a través del alfabeto estándar producirían + en el índice 62 y / en el índice 63. La conversión del resultado de base64url al estándar es una operación carácter por carácter: busque - y reemplácelo con +, busque _ y reemplace con /, y luego decodifique como de costumbre.

Los bytes que recupera son idénticos porque los índices eran idénticos; sólo los símbolos difieren. El relleno en base64url es opcional por convención, aunque el estándar lo permite. Los JWT están estructurados como tres segmentos de URL base64 unidos por puntos; cada segmento usa relleno si es necesario, pero muchas implementaciones lo omiten y dependen del hecho de que la aplicación consumidora conoce la longitud de bytes esperada.

Ejemplo resuelto: convertir un segmento de encabezado JWT a Base64 estándar: reemplazar caracteres, agregar relleno, decodificar a JSON

Un decodificador puede restaurar el relleno faltante dividiendo la longitud de la cadena por cuatro, calculando el resto y agregando los signos igual 0, 1 o 2. Si la longitud de la cadena no es múltiplo de cuatro, es evidente que falta relleno. Si la longitud es múltiplo de cuatro, la cadena se rellenó y luego se eliminó el relleno, o ya se ingresó un múltiplo de cuatro bytes (terminando con tres bytes en el bloque final, sin necesidad de relleno).

La concatenación de segmentos base64url requiere atención al relleno. Si cada uno de tres segmentos termina con =, la concatenación directa produce cadenas como AAAA=BBBB=CCCC=, donde el relleno en el medio ahora son caracteres perdidos, no marcadores de terminación. Esta es la razón por la que los JWT omiten el relleno en cada segmento: la estructura de tres segmentos es explícita, por lo que la decodificación se realiza de forma independiente en cada parte, y el relleno dentro del medio de la cadena concatenada es innecesario e interrumpiría el análisis.

Errores comunes: mezclar alfabetos en una cadena o codificar por ciento el estándar Base64 en lugar de usar base64url

Si crea una carga útil de múltiples segmentos, decida la convención de relleno al inicio: incluya en cada segmento y nunca concatene directamente, u omita y restaure desde la longitud solo al decodificar. El estándar RFC 4648 es autoridad en ambos alfabetos. La sección 4 especifica el estándar Base64; la sección 5 especifica base64url. Todo decodificador conforme debe indicar claramente qué alfabeto acepta.

El código que acepta base64url pero no Base64 estándar (o viceversa) implementa solo un subconjunto. El alfabeto base64url existe para compatibilidad con restricciones de URL y nombre de archivo; no es una mejora ni un reemplazo, solo una variante para un contexto específico. Cuando cree una API o un formato de token, elija un alfabeto y documente cuál. Un error común es codificar por ciento el estándar Base64 en lugar de usar base64url. La implementación también explica los límites del artículo. Normaliza los guiones y los guiones bajos antes de decodificar, pero no verifica la firma de un token ni interpreta las afirmaciones. Convertir un segmento JWT a bytes puede revelar JSON; no puede establecer quién emitió ese JSON o si alguien lo cambió.

Lo que esto no cubre: verificación de firmas JWT, base32 y otras codificaciones RFC 4648

%2B es el código de porcentaje para +; %2F es un código de porcentaje para /. La codificación porcentual convierte TWFu en TWFu sin cambios (sin caracteres especiales), pero TE9S+g== en TE9S%2Bg%3D%3D (demasiados caracteres para manejar). La solución correcta es utilizar base64url, que ya produce resultados seguros para URL. La codificación porcentual de Base64 es superflua y un desperdicio. Utilice el alfabeto correcto para el contexto. El codificador y decodificador Base64 acepta ambos alfabetos automáticamente.

Si pega una cadena que contiene -, la trata como base64url; si pega una cadena que contiene +, la trata como Base64 estándar. La herramienta también acepta URL y las trata como entradas seguras para URL. Por tanto, una comprobación práctica tiene dos resultados independientes: los bytes van de ida y vuelta y la representación elegida se ajusta a su canal. Pasar el primero dice que la transformación es reversible. Pasar el segundo dice que la puntuación y el relleno no serán reescritos por la URL, el nombre del archivo, la cookie o el protocolo que los contiene.

Conclusión: dos alfabetos, diseño de un bit: cómo el codificador y descodificador Base64 maneja el alfabeto estándar en el navegador y dónde indica en su página de herramientas lo que acepta

Al decodificar el segmento JWT o el token seguro para URL, puede pegarlo directamente sin conversión y la herramienta identifica el alfabeto a partir del contexto. Depurar la decodificación fallida se vuelve simple: pegue el token, vea si la herramienta lo acepta y, si no, intercambie caracteres manualmente e intente nuevamente.

La sustitución en sí es una línea de código, pero una decodificación fallida también puede deberse a una longitud imposible, un relleno mal colocado, corrupción o una entrada que no sea Base64. La herramienta normaliza ambos alfabetos automáticamente, por lo que la aceptación solo confirma que se pueden recuperar los bytes. Una carga útil JWT decodificada sigue siendo un reclamo sin firmar hasta que un verificador independiente verifica su firma y el algoritmo esperado.