Para qué sirve
Un JSON Web Token son tres bloques de texto separados por puntos: cabecera, contenido y firma. Los dos primeros son JSON escrito en Base64url, y eso significa que su interior está a la vista de cualquiera que tenga el token. Base64 no es cifrado: es una forma de escribir bytes con caracteres seguros para viajar por una URL o una cabecera HTTP.
De ahí sale la confusión que más caro se paga con esta tecnología. Un JWT va firmado, no cerrado. La firma garantiza que nadie ha cambiado lo que hay dentro sin conocer la clave, pero no impide leerlo. Poner el DNI de un cliente, un teléfono o un rol interno en el contenido equivale a publicarlo: quien reciba el token lo lee sin saber ningún secreto.
La otra distinción importante es entre descodificar y verificar. Descodificar es lo que hace esta página: separar los bloques y enseñar lo que llevan. No demuestra absolutamente nada, porque un token falsificado se descodifica igual de bien que uno legítimo. Verificar es recalcular la firma con la clave y comprobar que sale la misma, y es lo único que autoriza a fiarse del contenido.
Cómo se calcula
El token se parte por los puntos. La cabecera dice con qué algoritmo se firmó —el campo «alg»— y a veces con qué clave, en «kid». El contenido lleva las afirmaciones sobre quién es el portador y hasta cuándo vale. La firma es el resultado de aplicar el algoritmo a los dos primeros bloques tal cual viajan, sin descodificar.
Las fechas de un JWT no son las de JavaScript. El estándar las llama NumericDate y las cuenta en segundos desde el 1 de enero de 1970, mientras que un Date de JavaScript cuenta milisegundos. Confundirlos produce fechas del año 56000 en lugar de un error visible, y es el motivo por el que un token parece no caducar nunca.
Con HS256, HS384 y HS512 la firma es un HMAC: un resumen calculado con una clave secreta que conocen tanto el que emite como el que valida. Comprobarla solo requiere ese secreto, así que esta herramienta puede hacerlo entera dentro del navegador.
Con RS, PS, ES y Ed el esquema cambia: se firma con una clave privada y se comprueba con la pública correspondiente. Nadie salvo el emisor puede generar tokens, y cualquiera con la clave pública puede validarlos. Aquí se reconocen y se identifican, pero no se verifican, porque haría falta la clave pública del emisor y no un secreto compartido.
base64url(cabecera) · «.» · base64url(contenido) · «.» · firmaLos puntos separan los tres bloques. El tercero puede ir vacío, y entonces no hay nada que verificar.
firma = base64url( HMAC-SHA256( clave, «cabecera.contenido» ) )- clave
- el secreto compartido entre quien emite y quien valida
- cabecera.contenido
- los dos primeros bloques unidos por un punto, sin descodificar
Se firman los bloques tal cual viajan. Recodificar el JSON antes de firmar da una firma distinta aunque el contenido sea el mismo.
exp = 1767225600 → 1 de enero de 2026, 00:00 UTCSegundos, no milisegundos. Multiplicar por mil lleva al año 56000.
Ejemplo resuelto
Un token que el servidor rechaza
- Cabecera
- { "alg": "HS256", "typ": "JWT" }
- Contenido
- { "sub": "1234567890", "iat": 1735689600, "exp": 1767225600 }
- Momento de la consulta
- 11 de agosto de 2026
- El campo «iat» vale 1735689600, que en segundos son las 00:00 del 1 de enero de 2025: la fecha de emisión.
- El campo «exp» vale 1767225600, o sea las 00:00 del 1 de enero de 2026.
- La consulta es del 11 de agosto de 2026, más de siete meses después de esa fecha.
- El token se descodifica perfectamente y su firma puede ser correcta, pero está caducado: cualquier servidor que respete el estándar lo rechaza con un 401.
- Renovarlo no consiste en cambiarle el «exp» a mano. Eso invalidaría la firma, porque se calculó sobre el contenido antiguo. Hay que pedir uno nuevo a quien lo emite.
Caducado desde el 1 de enero de 2026
Los campos que define el estándar
El RFC 7519 reserva siete nombres. Todos son opcionales, y cada emisor añade además los suyos: un rol, un identificador de organización, un correo. Los reservados son los que cualquier biblioteca sabe interpretar sin que se lo expliquen.
| Campo | Nombre | Qué significa |
|---|---|---|
| iss | issuer | Quién emitió el token |
| sub | subject | De quién habla, normalmente el usuario |
| aud | audience | Para qué servicio es. Puede ser una lista |
| exp | expiration | Cuándo deja de valer |
| nbf | not before | Antes de este momento todavía no vale |
| iat | issued at | Cuándo se emitió |
| jti | JWT ID | Identificador único, para poder revocarlo |
El ataque del algoritmo «none»
El estándar admite el valor «none» en el campo «alg», pensado para casos donde la integridad ya está garantizada por otra capa. Un atacante puede aprovecharlo: coge un token legítimo, le cambia el contenido, pone «alg» a «none» y borra la firma.
Si la biblioteca del servidor decide cómo validar leyendo el propio token, aceptará ese token sin firma y el atacante entrará como quien quiera. La defensa es no preguntarle al token: el servidor debe fijar de antemano qué algoritmo espera y rechazar cualquier otro, incluido un HS256 donde esperaba un RS256.
Qué no debería ir dentro
Como el contenido se lee sin clave, no cabe nada que no se le enseñaría a quien tiene el token. Fuera datos personales que no hagan falta, fuera claves de API, fuera notas internas sobre el usuario.
Tampoco conviene que el token sea grande. Viaja en una cabecera HTTP en cada petición, y muchos servidores cortan por encima de ocho kilobytes. Lo habitual es guardar dentro un identificador y consultar el resto donde corresponda.
Preguntas frecuentes
¿Un JWT va cifrado?
No, salvo que sea un JWE, que se distingue porque tiene cinco bloques en vez de tres. El JWT firmado de toda la vida lleva el contenido en Base64url, que se revierte sin ninguna clave. Está protegido contra modificaciones, no contra lecturas.
¿Qué diferencia hay entre descodificar y verificar?
Descodificar solo traduce el Base64url a JSON y funciona con cualquier token, incluido uno inventado. Verificar recalcula la firma con la clave y comprueba que coincide con la que trae. Solo lo segundo demuestra que el contenido es el que puso el emisor.
¿Por qué me da 401 un token recién generado?
Lo más común es el desfase de reloj entre el servidor que emite y el que valida: si el primero va unos segundos adelantado, el «iat» o el «nbf» quedan en el futuro para el segundo. También pasa cuando el emisor calcula las fechas en milisegundos, o cuando el servicio espera un «aud» que el token no trae.
¿Puedo comprobar aquí una firma RS256?
No. RS256 se firma con una clave privada y se comprueba con la pública del emisor, así que no basta con escribir un secreto. Esta herramienta identifica el algoritmo y te lo dice, pero solo verifica los tres HMAC: HS256, HS384 y HS512.
¿Puedo pegar aquí un token de producción?
Técnicamente no sale de tu equipo: se descodifica con JavaScript en esta misma pestaña y el secreto se procesa con la criptografía del navegador. Dicho eso, la costumbre sana en cualquier equipo es tratar como quemado todo token que haya pasado por una herramienta, un chat o un ticket, y renovarlo. Si es un token que no puedes renovar, mejor prueba con uno de usar y tirar.
¿Puedo alargar la caducidad cambiando el «exp»?
No sin la clave. La firma se calculó sobre el contenido original, de modo que tocar una sola cifra la deja sin cuadrar y el servidor lo rechaza. Si tienes la clave puedes emitir uno nuevo, que es lo que hace de todas formas quien lo emite legítimamente.
Ten en cuenta
Fuentes
Toda la información de esta página se refiere a: Decodificador de JWT.