Decodificar vs Verificar un JWT: Diferencia Clave
Dev Tools

Decodificar vs Verificar un JWT: Diferencia Clave

Dos Operaciones Que Parecen Idénticas y No Lo Son

Escribe "decodificar JWT" en un buscador y la mayoría de los resultados te mostrarán encantados el contenido de cualquier token que pegues. Esa experiencia enseña una lección peligrosa — que leer un token es lo mismo que confiar en él. No lo es. Decodificar un JSON Web Token y verificarlo son dos operaciones completamente distintas con dos garantías de seguridad completamente distintas, y confundirlas está detrás de buena parte de las vulnerabilidades de autenticación y de los fallos de auth del tipo "funciona en mi máquina". Este artículo traza una línea clara entre ambas, explica exactamente qué hace cada una y muestra cómo probarlas en nuestro Decodificador JWT, que realiza la verificación localmente en tu navegador usando la Web Crypto API.

Qué Hace Realmente la Decodificación

Un JWT son tres segmentos codificados en base64url separados por puntos: header.payload.signature. La codificación se define en el RFC 7515 (JSON Web Signature), §2, y el propio base64url proviene del RFC 4648 §5 — una variante de base64 segura para URLs y sin requisito de relleno en el contexto de JWS. Decodificar un JWT no es más que dividir por los puntos y decodificar en base64url los dos primeros segmentos para recuperar el texto JSON.

Esa es toda la operación. Es una codificación de transporte reversible, no cifrado ni una comprobación de seguridad. No hay clave alguna, ni matemáticas más allá de una búsqueda en un alfabeto, ni posibilidad de fallo salvo una entrada malformada. Cualquiera — incluido un atacante que intercepte el token — puede decodificarlo al instante. Por eso el RFC 7519 (JSON Web Token) §10.1 advierte explícitamente de que un JWT basado en JWS no ofrece ninguna confidencialidad y el payload debe tratarse como público.

Decodificar responde a la pregunta "¿qué afirma este token?" Te dice el algoritmo de la cabecera, los claims iss, aud, sub y exp del payload, y cualquier dato personalizado que tu aplicación añadiera. Lo que no puede decirte es si algo de eso es cierto.

Qué Hace Realmente la Verificación

La verificación es una operación criptográfica. Toma la entrada de firma — los bytes exactos base64url(header) + "." + base64url(payload) — y recalcula la firma usando una clave, luego compara el resultado con el tercer segmento del token. Los algoritmos están catalogados en el RFC 7518 (JSON Web Algorithms): variantes HMAC como HS256 en §3.2, variantes RSASSA-PKCS1-v1_5 como RS256 en §3.3, y variantes ECDSA como ES256 en §3.4.

La verificación responde a una pregunta completamente distinta: "¿emitió este token alguien que posee la clave de firma, y ha sido alterado desde entonces?" Si cambia aunque sea un solo byte de la cabecera o del payload, la firma recalculada deja de coincidir y la verificación falla. Esa evidencia de manipulación es la razón de ser de un JWT. Sin verificación, los claims son solo texto no fiable que un atacante podría haber escrito.

Es crucial que la verificación pueda fallar, y que un fallo signifique algo. Decodificar un token falsificado tiene éxito y muestra claims controlados por el atacante; verificar ese mismo token falla ruidosamente. Esa diferencia — éxito silencioso frente a un rechazo criptográfico contundente — es exactamente la protección que tiras a la basura cuando tratas la decodificación como validación.

El Modelo Mental: Leer un Pasaporte vs Autenticarlo

Decodificar un JWT es como leer el texto impreso dentro de un pasaporte. Puedes ver el nombre, la nacionalidad, la fecha de caducidad. Cualquiera puede leer un pasaporte, y leerlo no demuestra que sea auténtico — una falsificación convincente también tiene texto perfectamente legible. Verificar la firma es como comprobar las características anti-manipulación del pasaporte contra los registros de la autoridad emisora. Solo ese segundo paso te dice que el documento es auténtico e inalterado. Un agente de fronteras que solo leyera los pasaportes sin autenticarlos dejaría pasar todas las falsificaciones, y un servidor que solo decodifica JWT sin verificarlos hace exactamente lo mismo.

Por Qué Esta Distinción Causa Vulnerabilidades Reales

Confiar en un claim decodificado

El error clásico es decodificar un token, leer "role": "admin" del payload y conceder acceso — sin verificar nunca la firma. Como el payload es legible y escribible por el atacante antes de firmar, cualquiera puede fabricar un token cuyo payload diga lo que quiera. Decodificarlo mostrará fielmente admin. Solo la verificación, contra una clave que el atacante no posee, rechaza la falsificación. El RFC 8725 (JWT Best Current Practices) §3.1 lo plantea como la regla fundamental: nunca actúes sobre claims de un token no verificado.

El downgrade "alg: none"

El RFC 7518 §3.6 define un algoritmo none — un JWT con firma vacía, pensado solo para contextos donde la integridad ya está garantizada por otros medios. Las primeras bibliotecas que confundían decodificar y verificar honraban lo que pidiera la cabecera del token, así que un atacante podía quitar la firma, poner "alg": "none" y lograr que el token se "verificara" contra ninguna clave. El RFC 8725 §3.1 y §2.1 señalan esto directamente y exigen que los verificadores fijen un algoritmo esperado en lugar de fiarse de la cabecera. Un decodificador puro, en cambio, simplemente te muestra alg: none — es el paso de verificación el que debe rechazarlo.

El ataque de confusión de claves HS256/RS256

Una versión más sutil, descrita en el RFC 8725 §2.2, explota un verificador que acepta el algoritmo que nombre la cabecera. Si un servicio espera RS256 (asimétrico, verificado con una clave pública) pero una biblioteca deja que el token imponga HS256 (simétrico, verificado con un secreto compartido), un atacante puede firmar un token falsificado usando la clave pública como si fuera el secreto HMAC. La clave pública es, por definición, pública. Fijar el algoritmo esperado durante la verificación derrota esto; decodificar nunca podría, porque decodificar no mira las claves en absoluto.

Decodificar vs Verificar un JWT: Diferencia Clave

Verificación Simétrica vs Asimétrica

Cómo verificas depende de cómo se firmó el token. Con un algoritmo simétrico como HS256, el mismo secreto firma y verifica mediante HMAC (RFC 7518 §3.2, construido sobre el RFC 2104). Emisor y verificador deben compartir ese secreto, lo que funciona dentro de un único límite de confianza pero no escala entre organizaciones y significa que el verificador también podría falsificar tokens. Con un algoritmo asimétrico como RS256 o ES256, una clave privada firma y la clave pública correspondiente verifica. Esto permite a un proveedor de identidad publicar su clave pública — normalmente como un JWK Set según el RFC 7517 — para que cualquier número de servicios verifique tokens sin poder acuñarlos. La cabecera kid del RFC 7515 §4.1.4 indica al verificador qué clave publicada usar. En nuestro Decodificador JWT pegas el secreto HMAC o la clave pública PEM; la Web Crypto API del navegador ejecuta la comparación localmente y tu clave nunca sale de la página.

Cómo Probar Ambas Operaciones con Seguridad

La forma más rápida de interiorizar la diferencia es verla suceder. Abre el Decodificador JWT y prueba esta secuencia:

  • Decodifica. Pega cualquier token. La cabecera y el payload se renderizan de inmediato, sin clave. Eso es decodificar — lectura pura.
  • Manipula. Cambia un carácter del payload (por ejemplo, altera un rol o un id de usuario) y vuelve a codificarlo. Decodifica de nuevo: los nuevos claims se muestran perfectamente, porque decodificar nunca comprueba la autenticidad.
  • Verifica. Ahora pega el secreto de firma o la clave pública y ejecuta la verificación. El token original se verifica; el manipulado se rechaza. Ese único estado en rojo es toda la razón por la que existe la verificación.

Como todo se ejecuta en el cliente, puedes hacerlo con tokens reales sin filtrarlos. Eso importa: pegar un token de sesión activo en un "depurador JWT" del lado del servidor transmite una credencial funcional a un tercero. El RFC 8725 §3.5 insiste en minimizar la exposición de los tokens; una herramienta solo local es la forma segura de respetar eso mientras inspeccionas tokens de producción. Combina el decodificador con nuestro Formateador JSON cuando un payload sea denso y quieras imprimirlo con formato, y con el Codificador Base64 cuando quieras decodificar a mano un solo segmento para ver tú mismo la mecánica del base64url en crudo.

Una Lista de Decisión para Ingenieros

  • ¿Necesitas leer un claim para mostrarlo o registrarlo? Decodificar está bien — pero etiqueta el dato como no fiable.
  • ¿Necesitas tomar una decisión de autorización? Debes verificar primero. Sin excepciones. Un claim decodificado está controlado por el atacante hasta que la firma demuestre lo contrario.
  • Fija el algoritmo. Configura tu verificador con el algoritmo esperado exacto; nunca dejes que la cabecera del token elija. Esto neutraliza tanto alg: none como los ataques de confusión de claves.
  • Valida los claims estándar tras verificar. Una firma válida solo prueba autenticidad. Aún debes comprobar exp, nbf, iss y aud según el RFC 7519 §4.1 para confirmar que el token es para ti, ahora mismo.
  • Mantén claves y tokens en local. Verifica con una herramienta del lado del cliente para que ni tu secreto ni tu token activo salgan de tu máquina.

Por Qué las Bibliotecas a Veces Difuminan la Línea

Muchas bibliotecas JWT exponen una única función de alto nivel que decodifica y verifica a la vez, lo cual es bueno — hace que el camino seguro sea el camino por defecto. El peligro aparece en bibliotecas (o código escrito a mano) que ofrecen un ayudante de "solo decodificar" por comodidad, porque los desarrolladores lo usan para leer un claim y luego olvidan que se saltó la verificación por completo. El nombre no siempre avisa: una función llamada decode en una biblioteca lanza un error con una firma inválida, mientras que en otra nunca toca la firma. En la duda, lee la documentación de esa función concreta y confirma si valida la firma — y si lo hace, qué clave usó y qué algoritmo fijó. Nuestro decodificador mantiene los dos pasos visualmente separados a propósito, para que la distinción que la API oculta sea la que la herramienta hace evidente.

Conclusión

Decodificar te dice lo que dice un token; verificar te dice si creerlo. Decodificar es una transformación de transporte sin clave que siempre tiene éxito, definida por el RFC 7515 y el RFC 4648. Verificar es una comprobación criptográfica contra una clave, regida por el RFC 7518 y endurecida por las buenas prácticas del RFC 8725, y es el único paso que hace fiable a un JWT. Toda vulnerabilidad seria de JWT — claims falsificados, alg: none, confusión de claves — se remonta a código que decodificó cuando debería haber verificado. Adquiere el hábito de preguntarte "¿verifiqué, o solo decodifiqué?" y confírmalo con el Decodificador JWT, que mantiene ambas operaciones locales, explícitas e imposibles de confundir. Para el panorama más amplio de cómo se estructuran y depuran los tokens, lee nuestra guía complementaria, Tokens JWT Explicados.

← Volver al Blog