Generador de JWT
Tu secreto se usa solo en esta página y nunca se envía, se almacena ni se añade a la URL — así que un enlace compartido no puede filtrarlo. Nunca pegues un secreto de firma de producción en ninguna web, incluida esta; usa un secreto desechable para pruebas.
Solo se admiten HS256, HS384 y HS512. Firmar con RS, ES y PS requiere una clave privada, que esta herramienta deliberadamente no pide.
Nada de lo que escribes aquí se almacena, registra ni comparte.
Construye un payload JWT, elige un algoritmo y fírmalo con tu secreto. La firma ocurre íntegramente en tu navegador, así que el secreto nunca sale de tu dispositivo.
Cómo usarlo
- Edita el payload como JSON.
- Opcionalmente elige una caducidad, lo que añade iat y exp por ti.
- Introduce tu secreto; el token firmado aparece debajo.
Qué produce la firma
Un JWT son tres segmentos base64url unidos por puntos. El primero es la cabecera, que indica qué algoritmo se usó. El segundo es el payload, con tus claims. El tercero es la firma, calculada sobre los dos primeros segmentos unidos por un punto; lo que se firma son los bytes exactos de esos segmentos, no el JSON al que se decodifican, y por eso volver a serializar un token lo invalida.
Con HS256, la firma es un HMAC de esa entrada con tu secreto. Cualquiera que tenga el mismo secreto puede recalcularla y ver si coincide, lo que demuestra dos cosas: que el token lo emitió alguien que conocía el secreto y que nada en él se ha alterado desde entonces. Cambia un solo carácter del payload y la firma recalculada ya no coincidirá.
Lo que no hace es ocultar nada. El payload está codificado, no cifrado, y cualquiera que tenga el token puede leer todas sus claims sin el secreto. No pongas nunca una contraseña, un número de tarjeta ni nada que no imprimirías en un log dentro del payload de un JWT.
Cómo elegir un secreto
La RFC 7518 exige una clave HMAC de al menos el tamaño de la salida del hash: 256 bits para HS256, 384 para HS384 y 512 para HS512. Eso significa 32 bytes aleatorios como mínimo, no una frase fácil de recordar.
El motivo es que un JWT es un ataque sin conexión listo para usar. Contiene juntas la entrada firmada y la firma, así que quien consiga un solo token puede probar secretos candidatos contra él tan rápido como su hardware lo permita, sin idas y vueltas por la red y sin nada que limite los intentos. Hay herramientas publicadas que hacen exactamente eso, y una palabra de diccionario o una cadena corta cae en segundos. Un token filtrado con un secreto débil significa que el atacante puede emitir sus propios tokens con las claims que quiera.
Usa un valor aleatorio de un gestor de contraseñas o un generador de claves, mantén secretos distintos por entorno para que un token de staging no pueda reutilizarse en producción y rótalos como harías con cualquier otra credencial.
Las claims que conviene establecer
Además de lo que necesite tu aplicación, la RFC 7519 registra un pequeño conjunto de claims estándar. iss indica el emisor, sub identifica al sujeto, aud indica la audiencia prevista y jti da al token un identificador único para poder revocarlo individualmente o detectar reutilizaciones. Las tres claims de tiempo - exp para la caducidad, nbf para el primer momento válido e iat para la emisión - son valores NumericDate, es decir, segundos desde la época Unix.
Segundos, no milisegundos. Poner directamente una marca de tiempo de JavaScript es el motivo más habitual por el que se rechaza un token escrito a mano: un exp de trece dígitos se interpreta como una fecha muy lejana en el futuro, que algunas bibliotecas rechazan sin más y otras aceptan como un token que nunca caduca.
Establecer exp no hace que el token caduque por sí solo. Caduca porque el verificador comprueba la claim, y un verificador que solo comprueba la firma aceptará encantado un token del año pasado. La mayoría de bibliotecas también toleran un pequeño desfase de reloj, normalmente uno o dos minutos, ya que las máquinas que emiten y verifican rara vez coinciden exactamente.
Por qué solo los algoritmos HS, y la trampa de alg
La familia HS es simétrica: un único secreto compartido sirve para firmar y para verificar, así que la firma puede hacerse aquí solo con lo que escribes. RS, ES y PS son asimétricos y requerirían pegar una clave privada en una página web, algo que esta herramienta no está dispuesta a pedir.
El campo de la cabecera que indica el algoritmo es también donde viven dos ataques muy conocidos. El primero es alg: none, que declara el token como no firmado; a las bibliotecas que lo aceptaban se les podían entregar tokens falsificados con la firma vacía. El segundo es la sustitución de algoritmo: se toma un token firmado con RS256, se cambia la cabecera a HS256 y se firma usando la clave pública del emisor como secreto HMAC. Un verificador que lee el algoritmo del token en lugar de decidirlo de antemano lo dará por válido, porque la clave pública no es secreta.
La defensa en ambos casos es la misma y corresponde al verificador, no al emisor: fija el algoritmo esperado en la llamada de verificación y rechaza cualquier token cuya cabecera no coincida.
Cómo diseñar la vida útil de un token
La decisión más determinante en un sistema de tokens es cuánto vive un token, porque un JWT no se puede retirar antes de que expire. Una vida corta - de cinco a quince minutos para un token de acceso - mantiene pequeña la ventana de un token filtrado y es la respuesta estándar, acompañada de un refresh token de mayor duración que sí se puede revocar porque el servidor lo almacena.
La rotación de refresh tokens hace que esa pareja sea bastante más segura: cada renovación emite un refresh token nuevo e invalida el anterior, así que un token robado sirve una sola vez. Si el antiguo se vuelve a presentar, el servidor se entera de que dos partes lo tienen y puede revocar toda la familia.
Cuando de verdad hace falta una credencial de larga duración - una integración entre máquinas, una CLI -, el JWT suele ser la forma equivocada. Una API key que se verifica contra una base de datos se puede revocar al instante, acotar con precisión y mostrar en una interfaz donde su dueño vea cuándo se usó por última vez.
Claves, rotación y el header kid
Una clave de firma debería poder rotarse sin una caída del servicio, y el mecanismo es el header kid: el emisor indica qué clave firmó el token y el verificador la busca en lugar de darla por supuesta. Con HS256 eso significa un pequeño mapa de identificadores de clave a secretos; con RS256 o ES256 significa un documento JWKS que el verificador descarga y guarda en caché.
La rotación tiene entonces tres fases. Publicar la clave nueva para que los verificadores la conozcan, pasar a firmar con ella sin dejar de aceptar la anterior, y retirar la antigua cuando todos los tokens firmados con ella hayan expirado. Saltarse ese solapamiento es lo que convierte una rotación rutinaria en un incidente.
Los algoritmos asimétricos compensan la preparación adicional en cuanto más de un servicio verifica tus tokens. Con HS256 cada verificador guarda un secreto que también sirve para firmar, así que cualquier servicio comprometido puede acuñar tokens; con RS256 los verificadores solo guardan una clave pública y no pueden falsificar nada.
Qué va en el payload y qué no
Un token es una credencial bearer que viaja en un header en cada petición, así que el tamaño tiene un costo real: los proxies suelen limitar los headers a 8 KB, y un token inflado se paga en cada llamada. Limítalo a la identidad y a los pocos datos que el verificador necesita: subject, issuer, audience, expiración y un conjunto reducido de scopes o roles.
Todo lo volátil encaja mal. Los permisos grabados en un token quedan desactualizados desde el momento en que se emiten, de modo que un rol revocado a las 10:00 lo siguen afirmando los tokens hasta que expiran. Donde eso importe, el token debería llevar la identidad y el servicio consultar la autorización, o la vida útil debería ser lo bastante corta como para que ese desfase sea tolerable.
Nada secreto tiene cabida ahí. El payload está codificado, no cifrado, así que cualquiera que tenga el token puede leer todas las claims: sin notas internas, sin datos personales más allá de los que el destinatario necesita, sin claves. Si un payload realmente debe ser confidencial, eso es JWE, una especificación distinta con herramientas distintas.
Probar tokens sin filtrar nada
Un generador resulta más útil para construir fixtures: un token expirado, uno que aún no es válido, uno con la audience equivocada, uno firmado con la clave equivocada. Una rutina de verificación debería probarse contra los cuatro, y la mayoría de los errores en esta área son casos en los que alguno de ellos se acepta.
Usa un secreto de prueba, nunca uno de producción. Es el mismo argumento que para cualquier credencial, y aquí es más tajante porque un token junto con su firma ya basta para un ataque offline contra el secreto. Tener secretos distintos por entorno también evita el fallo más sutil en el que un token acuñado en staging se acepta en producción.
Todo en esta página se ejecuta en el navegador, así que nada de lo que escribas aquí se transmite ni se guarda. Vale la pena saberlo, dado lo que la gente pega en herramientas de tokens, y es también la razón de que falten los algoritmos asimétricos: firmar con RS256 supondría pegar una clave privada en una página web, y ninguna herramienta debería pedir eso.
Razones habituales por las que se rechaza un token hecho a mano
Las claims de tiempo en milisegundos son lo más frecuente. NumericDate son segundos desde la epoch, así que un exp de trece dígitos se lee como una fecha a decenas de miles de años vista: algunas bibliotecas lo rechazan de plano y otras lo aceptan como un token eterno, y ninguna de las dos cosas es lo que buscabas.
Después viene el relleno. Los segmentos de un JWT usan base64url sin relleno, así que un token cuyos segmentos terminan en signos de igual, o que contiene caracteres de más y barra en lugar de menos y guion bajo, se codificó con el alfabeto equivocado y fallará antes incluso de que se compruebe la firma.
El resto suelen ser discrepancias. La audience que espera el verificador difiere en una barra final; el issuer está escrito con http mientras el verificador usa https; el reloj de una de las máquinas va unos minutos desfasado y no hay tolerancia configurada. Cuando un token se decodifica bien y aun así falla, compara las claims con la configuración del verificador campo por campo antes de sospechar de la firma.
Preguntas frecuentes
- ¿Es seguro introducir mi secreto de firma?
- El secreto lo usa solo el JavaScript de esta página. Nunca se transmite, se almacena ni se escribe en la URL, así que compartir un enlace no puede filtrarlo. Aun así, trata un secreto de firma de producción como una contraseña y usa un valor desechable para pruebas.
- ¿Por qué solo se admiten HS256, HS384 y HS512?
- Son simétricos, así que un único secreto compartido firma y verifica. RS, ES y PS son asimétricos y obligarían a pegar una clave privada en un formulario web, algo que esta herramienta evita pedir deliberadamente.
- ¿Qué deben contener iat y exp?
- Ambos son valores NumericDate medidos en segundos desde la época Unix, no en milisegundos. Elegir aquí una caducidad escribe los dos correctamente; aportarlos en milisegundos es la causa más habitual de que un token escrito a mano acabe rechazado.
- ¿Puedo añadir campos propios a la cabecera?
- La cabecera se fija con el algoritmo que elijas más typ JWT. Los miembros propios como kid pertenecen a una configuración concreta de gestión de claves, así que es mejor añadirlos desde la biblioteca que emite tus tokens reales.
- ¿Debería usar estos tokens en producción?
- No. Esta es una herramienta de pruebas y depuración. Los tokens reales debe emitirlos tu servicio de autenticación, que gestiona la rotación de claves, la revocación y la validación de claims.
Última actualización:
Incluye los pasos, el resultado esperado y el real. Elimina secretos y datos personales.
