Saltar al contenido
LeedyBox
Apoyar

Base64, codificación de URL y JWT explicados

Estos tres aparecen siempre que los datos tienen que viajar como texto: en URL, cabeceras HTTP, JSON y tokens de inicio de sesión. Ninguno oculta nada. Esta guía explica cómo funciona cada uno, dónde lo encontrarás y los errores que causan la mayoría de los problemas.

Codificar no es cifrar

Codificar cambia la forma en que se escriben los datos para que atraviesen un canal que solo acepta ciertos caracteres. Cualquiera puede revertirlo, porque no interviene ninguna clave. El cifrado también transforma los datos, pero solo quien tiene la clave puede recuperarlos. Un hash es otra cosa: una huella de un solo sentido que no se puede revertir, como se explica en Funciones hash explicadas.

Base64 y la codificación de URL son codificaciones. Un JWT suele estar firmado, lo que demuestra quién lo emitió y que no se modificó, pero su contenido solo está codificado. Si un valor debe permanecer secreto, necesita cifrado, no uno de estos formatos.

Cómo funciona Base64

Base64 lee los datos de tres en tres bytes (24 bits) y los divide en cuatro grupos de seis bits. Cada grupo es un número de 0 a 63 y se escribe como un carácter de un alfabeto de 64: A–Z para 0–25, a–z para 26–51, 0–9 para 52–61 y luego + y /. La palabra «Man» muestra los pasos:

PasoMan
Valores de byte7797110
Bits010011010110000101101110
Cuatro grupos de 6 bits010011 · 010110 · 000101 · 101110 = 19 · 22 · 5 · 46
Base64T W F u → TWFu

Cuando la longitud de la entrada no es múltiplo de tres, el último grupo se completa y se marca con relleno: un byte sobrante da dos caracteres y ==, dos bytes sobrantes dan tres caracteres y =. «Ma» se convierte en TWE= y «M» en TQ==.

Como cada tres bytes se convierten en cuatro caracteres, Base64 aumenta los datos en aproximadamente un tercio, más los saltos de línea que añaden algunos formatos. Una foto de 3 MB enviada como adjunto de correo viaja como unos 4 MB de texto, y una imagen incrustada en una hoja de estilos como URL de datos pesa alrededor de un tercio más que el archivo.

Dónde encontrarás Base64

  • Los adjuntos de correo (MIME) son texto Base64 cortado en líneas de 76 caracteres.
  • Las URL de datos, como data:image/png;base64,iVBORw0…, incrustan un archivo pequeño directamente en HTML o CSS.
  • La autenticación HTTP básica envía user:password en Base64 en la cabecera Authorization. Eso solo oculta la contraseña a simple vista, así que únicamente es segura con HTTPS.
  • Los certificados y las claves en archivos PEM son Base64 entre las líneas -----BEGIN …----- y -----END …-----, cortado a 64 caracteres.
  • JSON y XML llevan valores binarios, como una firma o una miniatura, en cadenas Base64 porque no tienen tipo binario.

Base64URL y el relleno

El + y la / del Base64 estándar tienen significado en las URL y en las rutas de archivo, así que un segundo alfabeto, Base64URL, usa - y _ en su lugar. Normalmente también omite el relleno =, ya que el decodificador puede calcular la longitud. Los JWT, muchos tokens de API y algunos nombres de archivo usan Base64URL. Para pasar de Base64 estándar a Base64URL, sustituye + por -, / por _ y elimina los = finales; para volver, deshaz las sustituciones y añade = hasta que la longitud sea múltiplo de cuatro.

Codificación porcentual en las URL

Una URL solo admite un conjunto limitado de caracteres, y algunos estructuran la dirección: / y ? separan la ruta y la consulta, & y = separan parámetros y # inicia el fragmento. Cuando un valor contiene uno de estos caracteres, o cualquier cosa fuera de ASCII, se codifica con porcentaje: cada byte de su forma UTF-8 se escribe como % seguido de dos dígitos hexadecimales. «café» se convierte en caf%C3%A9, porque é son los dos bytes C3 A9.

Las letras, los dígitos y - . _ ~ nunca necesitan codificarse. Estos son los caracteres que más problemas causan:

CarácterCodificadoPor qué importa
espacio%20No está permitido en una URL
&%26Iniciaría un nuevo parámetro
=%3DTerminaría el nombre del parámetro
?%3FIniciaría la consulta
#%23Iniciaría el fragmento, que no se envía al servidor
/%2FAñadiría un segmento de ruta
+%2BSe lee como espacio en los datos de formulario
%%25Iniciaría una secuencia de escape

Codifica cada valor por separado y luego arma la URL. En JavaScript, encodeURIComponent lo hace para un valor y también codifica / ? & = #, mientras que encodeURI está pensado para una dirección completa y deja esos caracteres intactos. Usar encodeURI con un solo valor es una causa frecuente de cadenas de consulta rotas.

Signos más, espacios y doble codificación

Los formularios HTML envían sus campos como application/x-www-form-urlencoded, donde un espacio se convierte en +. En la sintaxis general de URL, + es solo un signo más. Por eso una búsqueda de «C++» enviada como q=C++ llega como «C» seguido de dos espacios a un servidor que decodifica datos de formulario; debería enviarse como q=C%2B%2B. Cuando decodifiques una cadena de consulta a mano, averigua qué regla la generó.

La doble codificación ocurre cuando un valor ya codificado se codifica de nuevo: %20 pasa a %2520, porque el propio % se convierte en %25. Si ves %25 seguido de dos dígitos hexadecimales en una URL, algo en la cadena codificó dos veces; decodifica una vez y busca dónde ocurre el paso de más.

Qué contiene un JWT

Un JSON Web Token (JWT) transporta afirmaciones (claims), como quién es el usuario y hasta cuándo vale el token, desde el sistema que lo emite hasta los sistemas que lo aceptan. La forma firmada habitual tiene tres partes Base64URL separadas por puntos: una cabecera, una carga útil y una firma. Decodificadas, las dos primeras son JSON normal:

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

El estándar (RFC 7519) define algunas afirmaciones registradas; las aplicaciones añaden las suyas, como role arriba.

AfirmaciónSignificado
issEmisor: quién creó el token
subSujeto: normalmente el ID del usuario o de la cuenta
audAudiencia: el servicio al que va destinado el token
exp, nbf, iatCaduca, no antes de, emitido: tiempo Unix en segundos
jtiID del token, para detectar reutilizaciones o revocar un token concreto

Como la carga útil solo está codificada, cualquiera que tenga el token puede leerla. No incluyas datos personales ni secretos, y mantén los tokens pequeños: viajan con cada petición y muchos servidores limitan el tamaño de las cabeceras.

Firmado no es secreto: cómo se verifica un JWT

La firma se calcula sobre la cabecera y la carga útil. Con HS256, el emisor y el receptor comparten un secreto y usan HMAC con SHA-256. Con RS256 o ES256, el emisor firma con una clave privada y los receptores verifican con la clave pública correspondiente, así que no pueden crear tokens por su cuenta.

Un servidor que recibe un token debe verificar la firma con el algoritmo y la clave esperados, y comprobar exp, nbf, iss y aud, antes de confiar en cualquier afirmación. Decodificar, como hace la herramienta de LeedyBox, se salta todo eso: muestra lo que dice un token, no si es auténtico. Las bibliotecas también deben rechazar el algoritmo «none», que marca un token sin firma, salvo que se esperen tokens sin firmar. Cuando el contenido en sí debe quedar oculto, el token se cifra (JWE) y entonces tiene cinco partes que no se pueden leer sin la clave.

Problemas comunes y soluciones

SíntomaCausa probableSolución
Base64 se decodifica como texto ilegibleLos datos son binarios o texto en otra codificaciónComprueba qué se codificó; guarda los datos binarios como archivo
«Carácter no válido» al decodificarUn prefijo data:, comillas o el alfabeto Base64URLQuita todo lo que haya antes de la coma; usa un decodificador que acepte - y _
Un parámetro llega cortadoUn & o # sin codificar en el valorCodifica cada valor con encodeURIComponent
%2520 en una URLEl valor se codificó dos vecesCodifica una sola vez, en el punto donde se construye la URL
Token rechazado aunque exp está en el futuroAudiencia o emisor incorrectos, diferencia de relojes o clave distintaCompara aud, iss y la clave de firma con lo que espera el servidor
Caducidad dentro de miles de añosexp escrito en milisegundos en lugar de segundosGuarda exp, nbf e iat en segundos

Preguntas frecuentes

¿Sirve Base64 para proteger una contraseña o una clave de API?

No. Cualquiera puede revertir Base64 en un segundo. Una credencial codificada en Base64, por ejemplo en un archivo de configuración o en una URL, está tan expuesta como el texto plano.

¿Puedo poner datos personales en la carga útil de un JWT?

Evítalo. Cualquiera que tenga el token puede leer la carga útil, incluidas extensiones del navegador, registros y proxies que vean la petición. Pon un ID en el token y consulta los detalles en el servidor.

¿La codificación de URL protege contra ataques de inyección?

Solo en el sentido de que un valor no puede romper la estructura de la URL. El servidor sigue teniendo que validar y escapar el valor decodificado para el lugar donde lo use, como SQL, HTML o un comando de shell.

¿Por qué mi cadena Base64 es más larga que el archivo?

Cada tres bytes se convierten en cuatro caracteres, así que el texto es un 33 % más grande, y los saltos de línea añaden algo más. Para archivos grandes, enviar los bytes directamente es más eficiente que usar Base64.