Herramienta de Análisis JWT
Decodifica y verifica JSON Web Token, ver Header, Payload y Signature
JWT de Ejemplo
¿Qué es JWT?
JWT (JSON Web Token) es un estándar abierto (RFC 7519) para transmitir información de manera segura entre partes. JWT consta de tres partes separadas por puntos: Encabezado (Header) que contiene el tipo de token y algoritmo de firma, Carga (Payload) que contiene los datos de declaraciones, y Firma (Signature) que verifica la integridad del token. JWT se usa comúnmente para autenticación e intercambio de información. Al trabajar con JWT es importante distinguir decodificar de verificar. El header y el payload solo están codificados en Base64URL, por lo que pueden leerse aunque la firma sea inválida. La confianza aparece con la validación del servidor: firma, algoritmo, expiración, emisor y audiencia. Datos sensibles no deberían colocarse en un payload sin cifrar, porque cualquiera que posea el token puede leerlos. Depurar un token es útil, pero no equivale a aceptarlo.
Cómo usar
Cómo usar
- Pega un JWT en el campo de entrada; la herramienta analizará y mostrará automáticamente el contenido del header y el payload
- Haz clic en las etiquetas de colores para copiar la parte codificada en Base64 correspondiente
- Introduce el secreto en el área de verificación de firma para comprobar si la firma es correcta (soporta algoritmos HS256/HS384/HS512)
- El área de información clave muestra valores decodificados para claims comunes; el estado de expiración se indica por colores
Consejos de seguridad
- Esta herramienta se ejecuta localmente en tu navegador; el Token nunca se envía a ningún servidor
- JWT solo codifica y firma los datos, no está cifrado, cualquiera puede decodificar y ver el contenido
- No almacenes información sensible en JWT (como contraseñas o números de tarjetas de crédito)
- Usa siempre HTTPS para transmitir JWT en entornos de producción
Casos de uso
Principio técnico
JWT (JSON Web Token, RFC 7519) se compone de tres partes — Header.Payload.Signature — unidas por el punto inglés '.'. Header: describe el tipo de token y el algoritmo de firma, p. ej. {"alg":"HS256","typ":"JWT"}. alg determina cómo se calcula la Signature; los más comunes son HS256 (HMAC-SHA256), RS256 (RSA-SHA256), ES256 (ECDSA-SHA256) y none (sin firma, prohibido en producción). Payload: también llamado claims, un conjunto de campos JSON. RFC 7519 define 7 claims registrados estándar: iss (emisor), sub (sujeto, normalmente un ID de usuario), aud (audiencia), exp (expiración), nbf (no antes de), iat (emitido en) y jti (ID único). Los desarrolladores pueden añadir cualquier campo privado encima, como userId, role, tenant. Signature: codificar en Base64URL el Header y el Payload, unirlos con un punto y luego firmar con el algoritmo especificado por alg usando una clave. HS256 usa HMAC-SHA256(secret, header_b64 + '.' + payload_b64); RS256 usa una clave privada RSA. El receptor recalcula la firma de la misma manera y comprueba si ambas coinciden. Base64URL frente a Base64 estándar: '+' se convierte en '-', '/' se convierte en '_', y el relleno final '=' se omite, por lo que el resultado puede colocarse en rutas URL y cadenas de consulta sin activar la codificación porcentual. Ten en cuenta que Base64URL es solo una codificación: no proporciona cifrado ni seguridad, y cualquiera puede decodificar y leer el payload. Límite de seguridad: JWT solo garantiza 'no ha sido manipulado', no 'el contenido es sensible'. Un error común es incluir números de teléfono, números de identificación o hashes de contraseñas en el payload, donde todo el mundo puede verlos.
- Estructura de tres partes: Header.Payload.Signature, cada una codificada en Base64URL; la firma es HMAC(secret, header_b64 + '.' + payload_b64) o RSA(privateKey, misma entrada).
- Base64URL intercambia '+' -> '-', '/' -> '_', y omite el relleno final '=', por lo que el resultado codificado puede colocarse directamente en una URL (sin activar codificación porcentual).
- Esta herramienta solo verifica firmas de la familia HMAC (HS256/HS384/HS512) localmente. Algoritmos asimétricos como RS256 o ES256 requieren una clave pública del endpoint JWKS del emisor, así que la verificación de firma debe hacerse en un servidor que tenga la clave pública — la página puede decodificar el header y el payload, pero no puede verificarlos.
- Claims estándar: iss (emisor), sub (sujeto), aud (audiencia), exp (expiración, marca de tiempo Unix en segundos), nbf (no antes de), iat (emitido en), jti (JWT ID, previene reutilización).
- Ataque alg=none: el campo alg debe validarse estrictamente y el algoritmo none debe rechazarse, de lo contrario un atacante puede falsificar cualquier token; también deben prevenirse los ataques de sustitución de algoritmo (verificar un token HS256 usando la clave pública como secreto).
- JWT no está cifrado: el payload es texto plano codificado en Base64URL, no cifrado; para contenido confidencial usar JWE (JSON Web Encryption), pero en la práctica el patrón común es mantener los datos sensibles en el backend y referenciarlos mediante el campo sub.
Ejemplos
Token estándar HS256
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzA1MzEyODAwLCJleHAiOjE3MDUzMTY0MDB9.znHapMygT8K8YZN4K8zM1sV3bKlQ5pY3xE2gR4wN1vM
Header: {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"1234567890","name":"Jane Doe","iat":1705312800,"exp":1705316400}
RFC: RFC 7519 sección 3 define los Registered Claim Names (sub, iat, exp)Token expirado
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTEyMyIsImV4cCI6MTYwMDAwMDAwMH0.OxQ0fUKW0z4mK0xJ4vF0uF7eZB9wK3yF8pL2nQ6tX1k
Header: {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"user-123","exp":1600000000}
Estado: expirado (exp < ahora)
Nota: el claim exp usa NumericDate (segundos desde la época Unix según RFC 7519 sección 2)Token de información de usuario con claims personalizados
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTQ1NiIsIm5hbWUiOiJBbGljZSIsInJvbGUiOiJhZG1pbiIsInRlbmFudCI6ImFjbWUiLCJpYXQiOjE3MDUzMTI4MDAsImV4cCI6MTcwNTMxNjQwMCwiYXVkIjoiYXBpLmV4YW1wbGUuY29tIn0.7Hk2L9oP3qR1mN4vK8xJ2wE5yT6sB0fA9cZ1dG3hI4U
Header: {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"user-456","name":"Alice","role":"admin","tenant":"acme","iat":1705312800,"exp":1705316400,"aud":"api.example.com"}
Nota: role y tenant son claims privados; no están definidos en RFC 7519Lista de comprobación de seguridad para implementar JWT
1. Nunca almacenes secretos en el payload: JWT está codificado, no cifrado
2. Usa secretos fuertes para HS256 (>= 256 bits / 32 caracteres aleatorios)
3. Prefiere RS256/ES256 para verificación con clave pública en sistemas multi-servicio
4. Valida el header alg: rechaza 'none' o algoritmos inesperados
5. Verifica las marcas de tiempo exp, nbf, iat antes de confiar en el token
6. Comprueba que aud coincide con tu servicio para evitar la reutilización del token entre aplicaciones
7. Almacena en cookies HttpOnly, no en localStorage (protección XSS)
RFC: RFC 8725 (JWT Best Practices) cubre estas consideraciones de seguridadPreguntas frecuentes
¿Cuáles son las tres partes de un JWT?
Cabecera, payload y firma, separadas por puntos. La cabecera declara el algoritmo de firma y el tipo de token. El payload lleva reclamos como sub, iss, aud, iat, exp y cualquier dato personalizado. La firma permite al verificador confirmar que el token no ha sido manipulado. La cabecera y el payload son JSON codificado en Base64URL: están firmados, no cifrados.
¿Está cifrado un JWT?
No: un JWT en formato JWS normal está firmado pero no cifrado. Cualquiera que lo intercepte puede decodificar la cabecera y el payload con Base64URL y leer todos los reclamos, incluidos IDs de usuario, correos y roles. Trata el contenido de un JWT como información pública; nunca pongas contraseñas ni secretos en el payload. JWE (JWT cifrado) existe pero es mucho menos común.
¿Qué significa cada reclamo estándar?
iss = emisor; sub = sujeto (a menudo el ID de usuario); aud = audiencia (destinatario previsto); exp = expiración (segundos Unix); nbf = no antes de; iat = emitido en; jti = ID único del token para revocación. Están definidos por el RFC 7519. Los reclamos personalizados pueden añadirse libremente: ponle prefijo a los específicos de cada proveedor para evitar colisiones.
¿Cómo verifico un JWT?
Lee la cabecera alg, usa la clave correspondiente (HS256 = secreto compartido, RS256/ES256 = clave pública del endpoint JWKS del emisor), recalcula la firma sobre el header.payload codificado y compara. Después comprueba exp, nbf, iss y aud. Rechaza el token si alg es 'none' o difiere de lo que tu servidor espera. Esta herramienta solo verifica firmas HS256/HS384/HS512 (secreto compartido) localmente; la verificación de RS256/ES256 debe hacerse en un servidor que tenga la clave pública.
¿La verificación se hace en mi navegador?
Sí. La página analiza el JWT localmente y verifica las firmas HS256/HS384/HS512 con HMAC ejecutado en JavaScript dentro de tu navegador. El token no llega a nuestro servidor, pero recuerda que un JWT está diseñado para viajar en URLs y cabeceras — supón que cualquier JWT que copies puede aparecer en logs.
¿Por qué es peligroso alg=none?
El RFC 7519 permite alg=none para tokens sin firma. Un verificador vulnerable puede aceptar un token así aunque no tenga firma, lo que deja a un atacante falsificar cualquier payload. Las bibliotecas modernas rechazan alg=none por defecto; si escribes tu propio verificador, codifica fijo el algoritmo esperado en lugar de fiarte de la cabecera.
¿Cómo de grande puede ser un JWT?
No hay límite del protocolo, pero los JWT suelen acabar en cabeceras HTTP (Authorization: Bearer ...) y muchos servidores limitan las cabeceras a unos 8 KB. Meter reclamos en un JWT engorda cada petición. Si necesitas mucho estado de sesión, usa una sesión del lado del servidor y mete un pequeño token de referencia en el JWT en su lugar.