lab.m8d.io
Panel/Desarrollo/Decodificador JWT

Decodificador JWT

Decodifica y valida JSON Web Tokens

Desarrollo
Token JWT
Acerca de esta herramienta

El Decodificador JWT de lab.m8d.io analiza tokens JSON Web Token (RFC 7519) completamente en el lado del cliente, sin enviar el token a ningún servidor. Descompone las tres partes del JWT (header, payload y signature) con decodificación Base64URL, muestra todos los claims estándar (iss, sub, aud, exp, nbf, iat, jti) con fechas legibles y estado de expiración, e identifica el algoritmo criptográfico utilizado. La visualización codifica por colores cada segmento del token para facilitar el análisis.

Estructura interna de un JWT

Un JSON Web Token es una cadena compacta formada por tres segmentos separados por puntos (header.payload.signature), cada uno codificado en Base64URL (RFC 4648 sección 5, sin padding): • Header (JOSE Header) — Objeto JSON que declara el tipo de token (typ: "JWT") y el algoritmo de firma (alg). Opcionalmente incluye kid (Key ID) para identificar la clave en un JWKS (JSON Web Key Set), y jku (JWK Set URL) apuntando al endpoint que publica las claves públicas. Ejemplo: {"alg":"RS256","typ":"JWT","kid":"2024-key-1"}. El header se codifica en Base64URL sin padding y forma el primer segmento del token. • Payload (Claims Set) — Objeto JSON con los claims del token. RFC 7519 define siete claims registrados: iss (emisor), sub (sujeto), aud (audiencia), exp (expiración, timestamp Unix), nbf (no válido antes de), iat (momento de emisión) y jti (identificador único del token). Los claims privados contienen datos de la aplicación (roles, permisos, tenant_id). El payload NO está cifrado, solo codificado en Base64URL: cualquier persona con acceso al token puede leer su contenido. Para datos sensibles se usa JWE (JSON Web Encryption, RFC 7516). • Signature — Se calcula sobre la cadena Base64URL(header) + "." + Base64URL(payload) usando el algoritmo declarado en el header. Para HMAC: HMAC-SHA256(secret, input). Para RSA: RSASSA-PKCS1-v1_5-SHA256(privateKey, input). La firma garantiza integridad (el contenido no fue alterado) y autenticidad (fue emitido por quien posee la clave). El servidor receptor verifica la firma usando la clave simétrica (HMAC) o la clave pública (RSA/ECDSA) antes de confiar en los claims.

Algoritmos criptográficos y selección adecuada

La elección del algoritmo de firma (claim alg del header) tiene implicaciones directas en la seguridad y la arquitectura del sistema: • HS256 (HMAC-SHA256) — Algoritmo simétrico: la misma clave secreta se usa para firmar y verificar. Ventaja: rápido, simple, sin necesidad de gestión de pares de claves. Desventaja: el secreto debe compartirse entre emisor y todos los verificadores, creando un riesgo de compromiso proporcional al número de servicios que conocen la clave. Adecuado para monolitos o sistemas donde emisor y verificador son el mismo servicio. El secreto debe tener al menos 256 bits de entropía (32 bytes aleatorios); usar passwords cortos o predecibles permite ataques de fuerza bruta offline contra la firma. • RS256 (RSASSA-PKCS1-v1_5 con SHA-256) — Algoritmo asimétrico: se firma con clave privada y se verifica con clave pública. La clave pública se distribuye vía JWKS endpoint (/.well-known/jwks.json). Ideal para microservicios: el servicio de autenticación firma con su clave privada y los demás servicios verifican con la clave pública sin acceso al material sensible. Claves RSA de 2048 bits mínimo (4096 recomendado). PS256 (RSA-PSS) es la variante más segura pero menos compatible. • ES256 (ECDSA con P-256 y SHA-256) — Algoritmo asimétrico basado en curvas elípticas. Firmas y claves significativamente más pequeñas que RSA con seguridad equivalente (256 bits ECC ≈ 3072 bits RSA). Tokens más compactos, ideal cuando el tamaño importa (cookies, headers HTTP). P-256 es la curva estándar; P-384 (ES384) ofrece mayor margen de seguridad. EdDSA con Ed25519 (RFC 8037) es la opción más moderna con mejor rendimiento y resistencia a ataques de canal lateral. • none — Sin firma. Solo debe usarse en entornos de desarrollo local. Los servidores de producción deben rechazar tokens con alg:none explícitamente, ya que un atacante puede modificar el payload y eliminar la firma. Muchas bibliotecas JWT históricamente aceptaban alg:none por defecto, lo que constituye una de las vulnerabilidades más explotadas.

Vulnerabilidades comunes y prácticas de seguridad

Los JWT implementados incorrectamente son un vector de ataque frecuente en aplicaciones web y APIs: • Ataque alg:none — El atacante modifica el header para declarar "alg":"none", elimina la firma, y envía el token. Si el servidor no valida el algoritmo explícitamente y confía ciegamente en el header, acepta el token sin verificación. Mitigación: el servidor debe rechazar cualquier token cuyo algoritmo no coincida con la lista de algoritmos permitidos (allowlist), sin leer el alg del token para decidir el método de verificación. • Confusión HMAC/RSA — Si un servidor espera RS256, el atacante toma la clave pública RSA (que es conocida), la usa como secreto HMAC, cambia el header a "alg":"HS256" y firma el token. Si la biblioteca JWT despacha el algoritmo basándose en el header del token en lugar de una configuración fija, la verificación HMAC tendrá éxito con la clave pública como secreto. Mitigación: configurar el algoritmo esperado en el servidor, nunca derivarlo del token. • Secretos débiles — Claves HMAC como "secret", "password123" o el nombre de la aplicación permiten ataques de diccionario offline. Herramientas como jwt-cracker y hashcat pueden probar millones de candidatos por segundo contra la firma. Mitigación: usar secretos aleatorios de al menos 256 bits generados con CSPRNG (crypto.randomBytes(32) en Node.js). • Tokens sin expiración — Un JWT sin claim exp o con expiraciones excesivamente largas (meses, años) funciona como una credencial permanente. Si se filtra, el atacante tiene acceso indefinido. Mitigación: exp corto (5-15 minutos para access tokens), refresh tokens con rotación, y un mecanismo de revocación (blacklist en Redis o base de datos) para invalidación inmediata. • Validación incompleta de claims — No verificar aud (audiencia) permite que un token emitido para el servicio A sea aceptado por el servicio B. No verificar iss (emisor) permite tokens de proveedores de identidad no autorizados. Cada servicio debe validar iss, aud, exp, y nbf como mínimo. • JWT vs sesiones — Los JWT son stateless: el servidor no almacena estado de sesión, lo que facilita la escalabilidad horizontal. La desventaja es que la revocación inmediata requiere infraestructura adicional (blacklist). Las sesiones server-side con cookies opacas ofrecen revocación instantanea pero requieren almacenamiento centralizado (Redis, base de datos). La elección depende de los requisitos: microservicios distribuidos favorecen JWT; aplicaciones monoliticas pueden preferir sesiones clásicas.

Preguntas frecuentes

¿Es seguro pegar mi JWT en esta herramienta?
Sí. El Decodificador JWT de lab.m8d.io funciona completamente en el navegador usando JavaScript del lado del cliente. El token nunca se envía a ningún servidor: toda la decodificación Base64URL y el parsing JSON ocurren localmente. Puedes verificarlo inspeccionando el tráfico de red en las DevTools del navegador. Aun así, como buena práctica, evita pegar tokens de producción con acceso a datos sensibles en cualquier herramienta; usa tokens de desarrollo o de staging.
¿Esta herramienta verifica la firma del JWT?
Esta herramienta decodifica y muestra la estructura del JWT (header, payload y signature) pero no verifica la validez criptográfica de la firma, ya que para ello se necesita la clave secreta (HMAC) o la clave pública (RSA/ECDSA) del emisor. La verificación de firma debe realizarse siempre en el servidor backend con la clave correspondiente, nunca en el cliente. La herramienta si identifica el algoritmo declarado y muestra la firma codificada para inspección.
¿Cuál es la diferencia entre Base64 y Base64URL en un JWT?
Base64URL (RFC 4648 sección 5) reemplaza los caracteres + por - y / por _, y omite el padding con =. Esto hace que el token sea seguro para usar en URLs, query parameters y cabeceras HTTP sin necesidad de encoding adicional. Un JWT siempre usa Base64URL, no Base64 estándar. Si decodificas un JWT con un decodificador Base64 común, puede fallar o producir resultados incorrectos por los caracteres sustituidos.
¿Por qué mi JWT muestra 'expirado' si lo acabo de generar?
El claim exp se compara contra la hora actual del sistema del cliente (Date.now() / 1000). Las causas más frecuentes son: el reloj del servidor emisor y el del cliente están desincronizados (clock skew), el token se genero con un exp muy corto (segundos en lugar de minutos), o el timestamp exp esta en milisegundos en lugar de segundos Unix. RFC 7519 específica que exp debe ser un NumericDate (segundos desde epoch Unix, 1970-01-01T00:00:00Z). Muchas bibliotecas aplican un leeway de 30-60 segundos para tolerar clock skew.
¿Cuándo debería usar JWT en lugar de sesiones con cookies?
JWT es ideal en arquitecturas de microservicios donde multiples servicios necesitan verificar la identidad del usuario sin consultar un almacen centralizado de sesiones. También es la opción estándar para APIs consumidas por clientes moviles o SPAs que usan OAuth 2.0 / OpenID Connect. Las sesiones server-side con cookies son preferibles en aplicaciones monoliticas web donde la revocación inmediata es crítica (por ejemplo, al cambiar contraseña o detectar actividad sospechosa) y no se quiere implementar una blacklist de tokens.
¿Qué es un JWKS y para que sirve el claim kid?
Un JWKS (JSON Web Key Set, RFC 7517) es un documento JSON publicado en un endpoint conocido (típicamente /.well-known/jwks.json) que contiene las claves públicas del emisor. El claim kid (Key ID) en el header del JWT identifica cual clave del JWKS debe usarse para verificar la firma. Esto permite la rotación de claves sin interrumpir el servicio: el emisor firma con la clave nueva, los verificadores buscan la clave por kid en el JWKS, y las claves antiguas se retiran gradualmente. Proveedores como Auth0, Firebase, AWS Cognito y Azure AD publican sus JWKS automáticamente.