JWT Decoder — decodificador y verificador de JWT
Pega un JSON Web Token para leer su header y su payload, ver cuándo caduca y, opcionalmente, verificar la firma HMAC con tu secreto. Todo se ejecuta en tu navegador: el token nunca se sube a ningún servidor. Última revisión: 2026-06-19.
— — —
Qué es un JWT
Un JSON Web Token (JWT, que en inglés se pronuncia “jot”) es una forma compacta y
segura para URLs de transportar claims entre dos partes; lo más habitual es que sea el token de
inicio de sesión que recibe tu aplicación después de que un usuario se autentique. Tiene tres
partes separadas por puntos: header.payload.signature. El header y el payload son
objetos JSON que solo están codificados en Base64URL, así que cualquiera puede
leerlos: la firma es lo que demuestra que el token no ha cambiado y que lo emitió alguien que
posee la clave.
Las tres partes
- Header — el algoritmo de firma
(
alg, por ejemplo HS256 o RS256) y el tipo de token (typ). - Payload — los claims: sobre quién trata el token, quién lo emitió, cuándo caduca y cualquier dato personalizado.
- Firma — un hash con clave de
header.payload. Con HMAC usa un secreto compartido; con RSA/ECDSA usa la clave privada del emisor y se comprueba con la clave pública correspondiente.
Claims registrados
| Claim | Nombre | Significado |
|---|---|---|
iss | Emisor (Issuer) | Quién emitió el token (el servidor de autorización o la aplicación). |
sub | Sujeto (Subject) | Sobre quién trata el token — normalmente el ID del usuario. |
aud | Audiencia (Audience) | A quién va dirigido el token; el destinatario debe rechazarlo si él no es la audiencia. |
exp | Caducidad (Expiration) | Tiempo Unix a partir del cual el token no debe aceptarse. Más abajo se decodifica a una fecha legible. |
nbf | No antes de (Not before) | Tiempo Unix antes del cual el token no debe aceptarse. |
iat | Emitido el (Issued at) | Tiempo Unix en que se emitió el token. |
jti | JWT ID | Un identificador único, usado para impedir la reutilización (replay). |
Verificar la firma
La verificación vuelve a calcular la firma sobre los dos primeros segmentos y comprueba que
coincida con el tercero. Esta herramienta verifica la familia HMAC
(HS256, HS384, HS512) cuando aportas el secreto compartido,
usando el crypto.subtle nativo del navegador. Los tokens asimétricos
(RS256, ES256, PS256) se decodifican por completo, pero sus
firmas solo pueden verificarse con la clave pública del emisor (desde su endpoint
JWKS), así que aquí no se comprueban. Un token decodificado nunca es prueba de validez: confirma
siempre también exp, nbf, aud e iss.
Ejemplo resuelto
El clásico token de muestra del RFC 7519
que ves abajo usa HS256 con el secreto your-256-bit-secret. Su header se
decodifica como {"alg":"HS256","typ":"JWT"} y su payload como
{"sub":"1234567890","name":"John Doe","iat":1516239022}: ese iat
corresponde al 23 de enero de 2018. Pulsa Cargar ejemplo arriba para decodificarlo
y verificarlo al instante.
De dónde vienen los JWT: la familia JOSE
El JSON Web Token está definido por el RFC 7519 (mayo de 2015), uno de un conjunto de estándares relacionados conocidos colectivamente como JOSE (JavaScript Object Signing and Encryption). El mecanismo de firma que comprueba esta herramienta procede de JWS (JSON Web Signature, RFC 7515); la lista de algoritmos permitidos, como HS256 y RS256, procede de JWA (JSON Web Algorithms, RFC 7518); el formato para publicar claves públicas procede de JWK (JSON Web Key, RFC 7517); y existe un estándar aparte, JWE (JSON Web Encryption, RFC 7516), para los tokens cuyo contenido sí queda oculto. Un JWT normal —el que recibes al iniciar sesión en casi cualquier aplicación web moderna— es un JWS: firmado, pero no cifrado.
Firmado, no secreto
Lo más importante que hay que entender de un JWT estándar es que está firmado, no cifrado. El header y el payload están simplemente codificados en Base64URL —una codificación, no un cifrado—, así que cualquiera que tenga el token puede decodificar y leer todos los claims que contiene, exactamente como hace esta herramienta, sin ninguna clave. La firma no oculta el contenido; solo demuestra dos cosas: que el token no ha sido alterado desde que se emitió y que quien lo emitió poseía la clave de firma. La regla que se deriva de ahí es absoluta: nunca pongas en el payload de un JWT nada que el portador no deba poder ver — ni contraseñas, ni claves de API, ni datos personales sensibles. Si el contenido debe ser realmente confidencial, necesitas JWE (cifrado), no un simple JWT firmado.
HMAC frente a RSA/ECDSA: dos formas de firmar
Las firmas JWS se dividen en dos familias. Los algoritmos HMAC (HS256, HS384, HS512) son simétricos: un único secreto compartido crea y verifica la firma. Son sencillos y rápidos, e ideales cuando la misma parte emite y comprueba el token. Esta herramienta puede verificar tokens HMAC directamente porque, si tienes el secreto, dispones de todo lo necesario para recalcular la firma en tu navegador.
Los algoritmos RSA (RS256/384/512, PS256/…) y ECDSA (ES256/…) son asimétricos: el emisor firma con una clave privada que nunca comparte, y cualquiera puede verificar con la clave pública correspondiente. Esto es lo que usan los grandes proveedores de identidad, porque miles de servicios independientes pueden validar un token sin que se les confíe nunca el poder de emitir uno. Las claves públicas se publican en un endpoint well-known JWKS (JSON Web Key Set). Esta herramienta decodifica por completo los tokens asimétricos, pero no descarga claves remotas, de modo que no verifica sus firmas: esa comprobación corresponde a tu servidor, contra el JWKS del emisor.
¿Por qué usar un JWT? Autenticación sin estado
Una sesión web tradicional guarda un ID de sesión aleatorio en una cookie y mantiene los datos
reales de la sesión en la memoria del servidor o en una base de datos, así que cada petición exige
una consulta. Un JWT invierte esto: la identidad y los permisos del usuario van escritos
dentro del propio token firmado. Cuando llega una petición, el servidor solo tiene que
verificar la firma y leer los claims: ni viaje de ida y vuelta a la base de datos, ni almacén de
sesiones compartido. Esa ausencia de estado es lo que hace populares los JWT en
APIs, microservicios y sistemas escalados horizontalmente, donde cualquier servidor de la flota
puede validar un token por sí solo. El token se envía normalmente en cada petición en una cabecera
HTTP, como Authorization: Bearer <token>.
La otra cara de esa ausencia de estado es el problema de la revocación: como el
servidor no guarda ningún registro de los tokens emitidos, no puede "cerrar la sesión" de alguien
con facilidad antes de que su token caduque. Las mitigaciones habituales son caducidades cortas, una
lista de denegación en el servidor con los IDs de los tokens revocados (el claim jti) o
la rotación de la clave de firma; cada una reintroduce un poco de estado a cambio de control.
La vulnerabilidad "alg: none"
Las primeras librerías de JWT respetaban un valor de algoritmo especial, none, que
significa que el token está sin firmar. Un atacante podía tomar un token válido, cambiar el
payload (por ejemplo, pasar "role":"user" a "role":"admin"), poner el
algoritmo del header en none, borrar la firma, y un servidor ingenuo lo aceptaría. La
defensa es no aceptar nunca none en producción y validar el algoritmo
contra una lista blanca explícita en lugar de fiarse del valor que trae el propio header del token.
Esta herramienta marca como sin firmar y falsificable cualquier token cuyo header declare
alg: none.
El ataque de confusión RS256 a HS256
Un fallo más sutil y célebre es el ataque de confusión de algoritmos (o confusión de
claves). Un servidor espera RS256 (asimétrico) y verifica los tokens con la clave pública
del emisor, que es, por definición, pública. Si el código de verificación se fía del algoritmo que
nombra el token, un atacante puede cambiar el header a HS256 y firmar un token
falsificado usando esa clave pública como si fuera un secreto HMAC. Una librería que cambie a HMAC a
ciegas "verificará" entonces la falsificación contra la misma clave que usó el atacante. La defensa
es la misma que para alg: none: el servidor debe fijar el algoritmo
esperado y no dejar nunca que sea el token quien decida cómo se comprueba.
Valida algo más que la firma
Una firma válida solo demuestra que el token es auténtico y no ha sido alterado; no demuestra que el
token deba aceptarse ahora mismo. Un verificador correcto comprueba también los claims
registrados: exp (¿ha caducado?), nbf (¿se está usando demasiado pronto?),
aud (¿es este servicio la audiencia prevista?) e iss (¿lo emitió un emisor
de confianza?). Un token perfectamente firmado pero caducado, o destinado a otra audiencia, debe
rechazarse. Precisamente por eso un servidor puede rechazar legítimamente un token que esta
herramienta muestra con una firma HMAC válida.
Claims registrados, públicos y privados
El RFC 7519 divide los claims en tres grupos. Los claims registrados son los
nombres cortos y estándar de la tabla de arriba (iss, sub,
aud, exp, nbf, iat, jti): ninguno es
obligatorio, pero usarlos de forma coherente mantiene los tokens interoperables. Los claims
públicos son nombres registrados en el registro IANA de JSON Web Token o con un espacio de
nombres basado en un URI resistente a colisiones. Los claims privados son los campos
personalizados que acuerda tu propia aplicación: un role, una lista de
scopes, un ID de inquilino. Mantener los payloads pequeños importa: el token viaja en
cada petición, así que un JWT inflado se convierte en un coste real de ancho de banda y de tamaño de
cabecera en cada llamada.
Tokens de acceso, tokens de refresco y dónde guardarlos
Como un token de acceso robado da acceso hasta que caduca, los buenos sistemas los mantienen de vida
corta —a menudo de 5 a 15 minutos— y los combinan con un token de refresco de vida
más larga que solo sirve para obtener nuevos tokens de acceso y que puede revocarse de forma
centralizada. Dónde guardas un token en el navegador es en sí mismo una decisión de seguridad.
Guardarlo en localStorage es cómodo, pero lo expone a cualquier fallo de cross-site
scripting (XSS) de la página, que podría leerlo. Guardarlo en una cookie HttpOnly lo
oculta a JavaScript (mitigando el XSS), pero deja la petición expuesta a la falsificación de
peticiones entre sitios (CSRF) salvo que añadas el atributo SameSite o un token
anti-CSRF. No hay una única respuesta correcta, solo un compromiso informado para tu modelo de
amenazas.
Una lista de comprobación de seguridad para JWT
- Fija el algoritmo. Decide HS256 o RS256 en tu código y rechaza todo lo demás, incluido
none. - Usa un secreto HMAC fuerte. Para HS256 el secreto debería tener al menos 256 bits (32 bytes aleatorios) de entropía real: una palabra de diccionario se rompe por fuerza bruta sin conexión en unos instantes en cuanto un atacante tiene un token, porque la verificación es local e ilimitada.
- Mantén los payloads sin secretos. Da por hecho que todo lo que hay en un JWT firmado es legible por el portador.
- Define y comprueba
exp. Las vidas cortas limitan el daño de un token filtrado. - Valida
audeisspara que un token destinado a otro servicio o procedente de otro emisor no pueda reutilizarse contra ti. - Verifica los tokens asimétricos contra la clave pública del JWKS del emisor (cacheada y refrescada), nunca contra una clave incrustada en el propio token.
- Ten un plan de revocación —una lista de denegación por
jtio la rotación de claves— para los casos que una caducidad corta no puede cubrir.
Usados así, los JWT son una pieza robusta y bien conocida. La mayoría de los incidentes con JWT en el
mundo real no vienen de la criptografía, sino de comprobaciones que se saltan: aceptar
none, fiarse del algoritmo del header o usar un secreto HMAC adivinable; y todas ellas
son evitables.
Qué es la codificación Base64URL
Los puntos de un JWT separan tres segmentos codificados en Base64URL. Base64URL es
un pariente cercano del Base64 corriente que se puede poner sin problemas dentro de una URL:
sustituye los caracteres + y / por - y _, y
normalmente omite el relleno =. Esa es la única "transformación" que se aplica al header
y al payload —no hay compresión ni cifrado—, y por eso esta herramienta (y cualquier otra persona)
puede leerlos con nada más que el token. El segmento de la firma es la codificación Base64URL de los
bytes en bruto de la firma, no de texto, y por eso parece una ristra de caracteres
aleatorios en lugar de JSON legible.
JWT frente a tokens de sesión opacos
Un JWT no es el único tipo de token. La alternativa clásica es un token opaco: una cadena aleatoria larga que por sí sola no significa nada y que es simplemente una clave de búsqueda en un almacén de datos de sesión del lado del servidor. El compromiso es la imagen inversa del JWT: un token opaco no revela nada si se intercepta y puede revocarse al instante (basta con borrar el registro del servidor), pero cada petición exige esa consulta, así que no carece de estado. Un JWT no necesita ninguna consulta y escala sin esfuerzo entre servidores, pero es legible, más grande e incómodo de revocar antes de que caduque. Muchos sistemas usan ambos —JWT de vida corta para una autorización de API rápida, respaldados por un token de refresco opaco y revocable para renovarlos—, aprovechando las virtudes de cada uno.
Preguntas frecuentes
- ¿Se sube mi token a algún sitio?
- No. La decodificación y la verificación de la firma ocurren íntegramente en tu navegador mediante la Web Crypto API integrada. El token y el secreto nunca salen de tu dispositivo y nunca se registran ni se transmiten, así que es seguro inspeccionar tokens que sería arriesgado pegar en una herramienta que funcione en un servidor. Además sigue funcionando sin conexión una vez cargada la página.
- ¿Un JWT decodificado es secreto o está cifrado?
- No. Un JWT estándar está firmado, no cifrado: el header y el payload solo están codificados en Base64URL, así que cualquiera que tenga el token puede leerlos. La firma no oculta el contenido; únicamente demuestra que el token no ha sido manipulado y que lo emitió alguien que conoce la clave. Nunca pongas dentro del payload de un JWT secretos que no quieras que vea el cliente.
- ¿Qué firmas puede verificar esta herramienta?
- Verifica firmas HMAC —HS256, HS384 y HS512— cuando aportas el secreto compartido, usando la Web Crypto API nativa. Los algoritmos asimétricos (RS256, ES256, PS256, EdDSA) se decodifican por completo, pero sus firmas se validan con la clave pública del emisor, que solo está en su endpoint well-known, de modo que esta herramienta no las verifica.
- ¿Qué significa aquí "caducado"?
- Si el payload incluye un claim exp (caducidad) y ese momento ya ha pasado según el reloj de tu dispositivo, el token se muestra como caducado. Del mismo modo, un claim nbf (not-before) situado en el futuro se muestra como aún no válido. Estos datos se leen directamente de los claims decodificados; la comprobación de caducidad la hace normalmente el servidor que recibe el token.
- ¿Por qué la firma es "válida" pero el servidor sigue rechazando mi token?
- Una firma válida solo significa que el token no fue alterado y que la clave coincide. El servidor puede rechazarlo igualmente porque ha caducado (exp), se usa demasiado pronto (nbf), tiene una audiencia (aud) o un emisor (iss) equivocados, o fue revocado. Revisa también esos claims en el payload decodificado.
Herramientas relacionadas
Ver todas las herramientas del navegador → · Todas las conversiones para desarrolladores y datos →