Cómo Decodificar Tokens JWT de Forma Segura (Guía Paso a Paso)

25 Jan 2026 1,956 words

Cómo Decodificar Tokens JWT de Forma Segura

JWT (JSON Web Token) es un formato de token compacto y seguro para URL definido por RFC 7519. Se utiliza para autenticación e intercambio de información entre partes. Los JWT se han convertido en el estándar de facto para representar reclamos de forma segura entre dos partes, como un cliente y un servidor en una aplicación web moderna. Son autocontenidos, lo que significa que toda la información necesaria para autenticar una solicitud está incrustada directamente en el propio token, eliminando la necesidad de almacenamiento de sesión del lado del servidor en muchas arquitecturas.

La popularidad de los JWT abarca aplicaciones de una sola página, aplicaciones móviles, puertas de enlace API y comunicación entre microservicios. Cuando un usuario inicia sesión en una aplicación, el servidor emite un JWT que el cliente almacena y presenta con cada solicitud posterior. El servidor luego verifica la firma del token para autenticar y autorizar la solicitud. Entender cómo decodificar e inspeccionar JWT de forma segura es crítico para los desarrolladores que necesitan depurar flujos de autenticación, verificar reclamos y solucionar problemas relacionados con tokens sin exponer datos sensibles ni introducir vulnerabilidades.

Comprendiendo la Estructura JWT

Un JWT consta de tres partes separadas por puntos, cada una codificada usando Base64URL (una variante segura para URL de la codificación Base64):

header.payload.signature

Ejemplo:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwi
bmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4
fwpMeJf36POk6yJV_adQssw5c

El primer segmento es el encabezado, que contiene metadatos sobre el token, incluyendo el algoritmo de firma y el tipo de token. El segundo segmento es la carga útil, que contiene los reclamos o afirmaciones que se hacen. El tercer segmento es la firma, que se calcula tomando el encabezado y la carga útil codificados, combinándolos con un punto, y firmando el resultado usando el algoritmo especificado en el encabezado junto con una clave secreta o clave privada.

Detalle de la Codificación Base64URL

JWT utiliza codificación Base64URL, que difiere de Base64 estándar en dos aspectos importantes. Primero, reemplaza el carácter + con - para evitar problemas en los parámetros de consulta URL donde + se interpreta como un espacio. Segundo, reemplaza el carácter / con _ para evitar conflictos con los separadores de ruta URL. Además, los caracteres de relleno (=) se eliminan del final de los segmentos JWT porque son innecesarios para la decodificación y solo añadirían bytes innecesarios al token.

Reclamos del Encabezado JWT

El encabezado típicamente contiene el algoritmo y el tipo de token, pero también puede incluir metadatos adicionales para escenarios avanzados.

Reclamo Nombre Ejemplos de Valores
alg Algoritmo HS256, RS256, ES256
typ Tipo de Token JWT
kid ID de Clave unique-key-id
jku URL del Conjunto JWK https://example.com/.well-known/jwks.json

El reclamo kid (ID de Clave) es particularmente importante en entornos donde múltiples claves de firma están en rotación. Permite que el servidor busque la clave correcta de un conjunto de claves sin adivinar. El reclamo jku apunta a una URL que contiene un Conjunto de Claves Web JSON (JWKS), que el verificador puede obtener para obtener la clave pública para la verificación de la firma. Sin embargo, obtener claves de URLs especificadas en tokens no confiables introduce riesgos de seguridad y solo debe hacerse con una validación adecuada.

Reclamos Comunes de la Carga Útil JWT

La carga útil contiene reclamos que proporcionan información sobre el usuario y el propio token. Estos reclamos se clasifican como registrados, públicos y privados.

Reclamo Nombre Descripción
sub Sujeto Identificador de usuario
iss Emisor Quién emitió el token
aud Audiencia Destinatario previsto
exp Expiración Marca de tiempo de vencimiento del token
nbf No Antes De Token válido desde
iat Emitido En Momento de creación del token
jti ID JWT Identificador único del token

Los reclamos registrados están estandarizados por la especificación JWT y tienen significados específicos. El reclamo exp es particularmente crítico para la seguridad. Si un token no incluye un tiempo de expiración, o si el servidor no lo valida, el token permanece válido indefinidamente, creando una vulnerabilidad grave si el token alguna vez se filtra. El reclamo iat registra cuándo se creó el token y puede usarse para determinar la antigüedad del token o para implementar políticas de rotación de tokens.

Más allá de estos reclamos registrados, las aplicaciones típicamente incluyen reclamos personalizados para roles de usuario, permisos, direcciones de correo electrónico y otros datos específicos de la aplicación. Por ejemplo, un token podría incluir "role": "admin" o "permissions": ["read", "write", "delete"]. Estos reclamos personalizados deben inspeccionarse cuidadosamente, pero nunca confiarse sin verificación de firma.

Decodificar vs Verificar

La distinción entre decodificar y verificar es el concepto más importante de entender al trabajar con JWT. Confundir los dos es una fuente común de vulnerabilidades de seguridad.

Decodificar simplemente decodifica en Base64URL el encabezado y la carga útil. Cualquier persona puede decodificar un JWT sin ninguna clave secreta. Puedes decodificar cualquier JWT pegándolo en una herramienta de decodificación o ejecutando una función simple de decodificación Base64URL en los dos primeros segmentos. Esto hace que los JWT sean útiles para inspección y depuración, pero también significa que el contenido de la carga útil es legible públicamente.

Verificar comprueba la firma usando una clave secreta (HMAC) o clave pública (RSA/ECDSA). Esto confirma que el token no ha sido manipulado y que fue emitido por una parte confiable. La verificación es el paso que proporciona seguridad. Sin ella, un atacante podría modificar la carga útil para cambiar el ID de usuario o el rol, recodificar el encabezado y la carga útil, y crear una nueva firma que parecería válida para un servidor que omita o implemente incorrectamente la verificación de firma.

Ataques de Confusión de Algoritmo

Una de las vulnerabilidades JWT más peligrosas es el ataque de confusión de algoritmo, también conocido como ataque de confusión de clave. Este ataque explota el hecho de que el algoritmo se especifica en el encabezado, que está controlado por el atacante ya que el encabezado solo está codificado en Base64URL y no está cifrado.

En un escenario típico, un servidor usa RS256 (RSA con SHA-256) para firmar tokens. La clave pública del servidor está ampliamente disponible, mientras que la clave privada se mantiene en secreto. Un atacante intercepta un token válido y cambia el encabezado alg de RS256 a HS256. Dado que HS256 usa una clave secreta simétrica, el servidor intentará verificar la firma usando el algoritmo HS256. El error crítico es si el servidor usa la clave pública RS256 como el secreto HS256. Dado que la clave pública es pública, el atacante puede calcular una firma HS256 válida para cualquier carga útil usando la clave pública como secreto HMAC. El servidor luego verifica la firma usando la misma clave pública y acepta el token falsificado.

Para prevenir este ataque, los servidores deben validar que el algoritmo coincida con el algoritmo esperado antes de verificar, o usar una biblioteca que sea inmune a este ataque por diseño. Muchas bibliotecas JWT modernas ahora usan métodos separados para verificación asimétrica y simétrica para eliminar este riesgo.

Pasos para una Decodificación Segura

Sigue estos pasos cada vez que necesites decodificar e inspeccionar un token JWT.

  1. Copia el token JWT de tu aplicación. Asegúrate de haber capturado el token completo incluyendo los tres segmentos separados por puntos. Un token parcial fallará al decodificarse correctamente.

  2. Usa una herramienta de decodificación confiable como Decodificador JWT que se ejecute completamente en el navegador o en tu máquina local. Evita pegar tokens en herramientas en línea desconocidas que puedan registrar o transmitir tus tokens a servidores remotos. Incluso si un token es de corta duración, exponerlo a un tercero podría permitirle reutilizarlo dentro de su ventana de validez.

  3. Inspecciona el encabezado para ver el algoritmo. Confirma que el algoritmo coincida con lo que esperas que use tu servidor. Si ves un algoritmo inesperado como none o un cambio de RS256 a HS256, trata el token como sospechoso.

  4. Revisa los reclamos de la carga útil. Verifica las marcas de tiempo exp (expiración) y nbf (no antes de) para confirmar que el token es actualmente válido. Verifica que el iss (emisor) coincida con el identificador de tu servidor. Comprueba que el reclamo aud (audiencia), si está presente, incluya tu aplicación.

  5. Nunca compartas el token públicamente. Los tokens publicados en informes de errores, preguntas de Stack Overflow o GitHub gists pueden ser mal utilizados por cualquiera que los encuentre antes de que expiren. Siempre redacta o reemplaza los tokens con ejemplos ficticios antes de compartir.

  6. Nunca verifiques con claves no confiables. Si tu código de verificación acepta claves de entrada de usuario, URLs remotas o archivos de configuración que pueden ser modificados por atacantes, todo tu sistema de autenticación está comprometido.

Decodificando JWT en Código

Si bien las herramientas en línea son convenientes para inspección ad-hoc, a menudo necesitarás decodificar JWT mediante programación en tu aplicación. Aquí se explica cómo decodificar una carga útil JWT en algunos lenguajes de programación populares sin realizar verificación de firma.

JavaScript (Node.js)

function decodeJWT(token) {
  const payload = token.split('.')[1];
  const decoded = Buffer.from(payload, 'base64url').toString('utf8');
  return JSON.parse(decoded);
}

const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
console.log(decodeJWT(token));

Python

import base64
import json

def decode_jwt(token):
    payload = token.split('.')[1]
    # Add padding for base64 decoding
    padding = 4 - len(payload) % 4
    if padding != 4:
        payload += '=' * padding
    decoded = base64.urlsafe_b64decode(payload)
    return json.loads(decoded)

token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
print(decode_jwt(token))

Estos ejemplos demuestran la decodificación solo con fines de inspección. Para verificación en producción, usa siempre una biblioteca JWT bien auditada que maneje la validación de algoritmos, la gestión de claves y la verificación de firmas correctamente.

Mejores Prácticas de Seguridad

Más allá de la decodificación segura, seguir estas mejores prácticas mantendrá segura tu implementación JWT.

Usa tiempos de expiración cortos. Los tokens de acceso deberían expirar entre 15 y 60 minutos. Los tokens de corta duración limitan el daño si un token se filtra. Combina los tokens de acceso con tokens de actualización que tengan vidas más largas y puedan revocarse individualmente.

Valida todos los reclamos requeridos. Siempre verifica los reclamos exp, nbf, iss y aud durante la verificación. Muchos ataques explotan la validación de reclamos faltante o incorrecta.

Usa algoritmos asimétricos para sistemas distribuidos. RS256 o ES256 permiten que el servidor firme tokens con una clave privada mientras cualquier servicio puede verificarlos con la clave pública. Esto elimina la necesidad de compartir secretos entre servicios.

Implementa listas negras de tokens. Para escenarios donde necesites revocar tokens antes de que expiren, mantén una lista negra o usa un número de versión de token almacenado en tu base de datos. Incrementa la versión en cambios de contraseña o suspensión de cuenta para invalidar todos los tokens existentes.

Advertencia de Seguridad

Nunca aceptes tokens de fuentes no confiables. Siempre verifica la firma en tu servidor antes de confiar en la carga útil. Ten en cuenta los ataques de confusión de algoritmo donde un atacante cambia RS256 a HS256 para usar la clave pública como secreto. Usa bibliotecas JWT de buena reputación que implementen la verificación de firma de forma segura, y mantenlas actualizadas para beneficiarte de los últimos parches de seguridad.

Recuerda que decodificar no es verificar. Cualquier persona puede leer el contenido de un JWT simplemente decodificando la carga útil en Base64. Trata las cargas útiles JWT como información pública en lo que respecta a la confidencialidad, y confía en la verificación de firma para la integridad y autenticidad.


About this article

Aprende cómo decodificar tokens JWT de forma segura para inspeccionar su contenido sin comprometer la seguridad.


Related Articles


Related Tools

Help2Code Logo
Menu