Skip to main content
Json Web Tokens (JWT) Qué son y como funcionan

Json Web Tokens (JWT) Qué son y como funcionan

JWT son las siglas de Json Web Token. JWT es un estándar abierto (RFC 7519) que define una forma compacta y autónoma de transmitir datos de forma segura entre dos partes por medio de tokens en formato json

Bienvenidos a un nuevo post en Byte Mind, en el caso de hoy vamos a ver que son los Json Web Tokens, conocidos por sus siglas como JWT, cómo es su estructura, para qué se utilizan y las posibles vulnerabilidades existentes en los mismos.

 

¿Qué es un JWT?

JWT son las siglas de Json Web Token. JWT es un estándar abierto (RFC 7519) que define una forma compacta y autónoma de transmitir datos de forma segura entre dos partes por medio de tokens en formato json, Estas pueden contener usuarios, servidores o cualqueir combinación de servicios y se firman digitalmente por lo que la parte receptora puede confiar en los datos contenidos en el mismo.

El cliente utilizará sus credenciales para autenticarse en el servidor sólo una vez. Durante este tiempo, el servidor validará las credenciales y devolverá al cliente un Json Web Token que podrá utilizar para solicitudes futuras, y por lo tanto, no necesita enviar las credenciales de nuevo. Además, una de las principales ventajas, es que es muy compacto, por lo que pueden enviarse a través de una solicitud POST, un encabezado HTTP o una consulta dentro de un URL, aunque sólo deberá incluir la información necesaria para la parte receptora.

Los JWT son también autónomos, lo que significa que puede abarcar los siguientes puntos:

  • Información de identiciación de un usuario
  • Las secciones a las que puede acceder el usuario
  • Fecha de caducidad
  • Firma para la validación de contenido
  • Cualquier otro tipo de información serializable

Hay que tener en cuenta, que los token JWT, pueden ser decodificados por cualquier sin necesidad de disponer de las claves privadas, por esta razón, nunca se debe incluir información sensible como contraseñas en los mismos. El propósito de un JWT no es cifrar datos para que no se puedan leer durante el transporte (para eso está SSL) sino que permite que la parte receptora confíe en que los datos recibidos no se hayan modificado durante el transporte.

 

Estructura de un JWT

Un JWT se compone de tres partes, Cabecera, Carga útil y Firma (Header, Payload y Signature). Cada una de estas partes se separa de la anterior mediante un carácter “.” y es un texto en formato json y codificado en Base64url.

Estructura de un JWT

 

Un ejemplo de un token se puede ver en la siguiente captura

 

Veamos a continuación en detalle cada una de las partes.

 

Header

La primera sección se conoce como Encabezado o Header en inglés. Aquí es donde se encuentran algunas piezas clave del token:

  • alg -> el algoritmo utilizado para firmar el token (por ejemplo, HS256 para HMAC SHA-256 o RS256 para RSA SHA-256). Se recomienda utilizar RS256 porque utiliza claves asimétricas (pública/privada) en lugar de confiar en una clave privada compartida.
  • x5t -> (opcional) es la huella digital del certificado, que contiene un SHA-1 codificado en base64url del certificado X509 correspondiente a la clave de cifrado utilizada
  • jku -> la URL de la clave web Json (JWK)
  • kid -> (opcional) indica qué clave de cifrado se ha utilizado. Este se puede utilizar como una señal para los destinatarios de que una clave se ha cambiado.
  • typ -> tipo del token. Este parámetro es opcional, sin embargo, si está preestablecido se recomiendo que el valor sea JWT (siempre en mayúsculas).

Aquí no vemos todos los parámetros existentes, pero sí los más utilizados. Además cabe destacar que esta sección el tema general es el cifrado, por lo cual también puede verse esta sección denominada Json Web Encryption (JWE).

 

Payload

La segunda parte es el payload (también conocida como claims, reclamos), en la cual el emisor del JWT puede almacenar información personalizada para la parte receptora.

En este caso tenemos tres tipos de notificaciones que se pueden utilizar en el payload: Public, Private y Registered.

  • Public -> deben ser resistentes a colisiones, por lo que tienen que ser únicos para garantizarque no haya payloads públicos con el mismo nombres. Todos deben definirse en el IANA JSON Web Token Registry o definirse como un URI que contiene un namespace único.
  • Private -> los payload privados no tienen que ser resistentes a colisiones y pueden tener cualquier nombre, siempre y cuando, la parte emisora y la receptora estén de acuerdo con el uso de la misma.
  • Registered -> son payloads universalmente definidas que se reservan para fines específicos. Algunos de los más comunes son:
    • aud -> audiencia del token, es decir, a quién está destinado.
    • exp -> fecha de vencimiento del token, en formato NumericDate.
    • iat -> hora en la que se emitió el token.
    • iss -> token issuer.
    • jti -> identificador único del token.
    • nbf -> tiempo de duración del token.
    • sub -> sujeto del token.

 

Signature

La última sección es la firma. Esta será la encargada de hacer seguro el JWT y garantizar la integridad del mismo durante su transporte. La firma es simplemente un hash de todo el contenido que se generó con el Json Web Token, lo que significará que si alguna parte del token cambia, la firma será inválida, y por lo tanto provocará que el token tenga un formato incorrecto. Un JWT se firma con un JSON Web Algorithm (JWA).

El algoritmo para generar una firma RS256 sería el siguiente:

Como acabamos de ver, el algoritmo coge el encabezado y el payload codificados, concatenados por un punto, y los firma con una clave que sólo conoce el servicio que generó el JWT. Esto, también es conocido como Json Web Signature (JWS).

Nota: Siempre se deben validar los JWT en el extremo receptor. Debido a que los payloads simplemente están codificados en Base64url, es posible decodificar un JWT sin validar realmente de donde proviene o si su firma es correcta. Si no se validan los token al decodificar, cualquiera podría enviar un JWT personalizado, poniendo en riesgo la seguridad de su aplicación. La mayoría de los paquetes JWT manejan la validación automáticamente, pero nunca se debe asumir que sea así sin haberlo revisado antes.

Si su emisor utiliza RS256 para firmar tokens, necesitará una clave pública para validar el token, pero ¿cómo se puede obtener la clave pública?. Bueno esa pregunta la responderemos más adelante.

 

Uso de JWT

Un JWT, generalmente, se adjunta a una solicitud HTTP a través del encabezado Authorization como un token. Vemos un ejemplo a continuación:

 

Con cada solicitud, se deberá enviar el JWT, de tal forma que pueda proporcionar una forma de autenticación sin estado, debido a que el servidor no tiene que recordar la información del usuario en el almacenamiento de la sesión, lo que reduce de forma significativa la cantidad de trabajo necesaria para administrar dicho estado en el backend.

Un inconveniente de esto, es que los token no tienen estado, por lo que no pueden invalidarse sin almacenar el estado de la sesión.

Los token se invalidarán automáticamente una vez cumplida la fecha de vencimiento de los mismos, pero dependiendo de cuanto tiempo se haya establecido, el usuario podría ser capaz de conservar el acceso a un servicio después de haber sido eliminado el token.

 

 

Por qué debería utilizarse

Vamos a hablar de los beneficios del uso de Json Web Tokens (JWT) en comparación con Simple Web Tokens (SWT) y Security Assertion Markup Language Tokens (SAML).

Una diferencia fundamental es el formato de los datos, un fichero json es menos detallado que un xml, además, su tamaño es más pequeño lo que lo hace más compacto y que sea una buena opción para utilizar en entornos web.

Con respecto a la seguridad, SWT sólo puede firmar de forma simétrica mediante un secreto compartido utilizando el algoritmo HMAC, mientras que JWT y SAML pueden utilizar un par de claves público/privada en forma de certificado X.509 para la firma. Además firmar XML con XML Digital Signature sin introducir grandes agujeros de seguridad es muy complicado, en comparación con la facilidad de firmar un JSON.

Los analizadores JSON son comunes en la mayoría de lenguajes de programación porque se asignan directamente a los objetos, mientras que un XML no tiene un mapeo natural de documento a objeto, lo que hace más fácil trabajar con JWT que con SAML.

Como ya se ha comentado el uso de JWT es bastante más sencillo y seguro en comparación con otros método, lo que lo hace especialmente útil.

 

 

Esto es todo por el momento, espero les haya gustado y nos vemos próximamente en otro post, en el que indicaremos los diferentes tipos de ataques y vulnerabilidades existentes en JWT.

Y como siempre, cualquier aporte, duda o sugerencia es bienvenida en la sección de comentarios.

 

Deja una respuesta

Tu dirección de correo electrónico no será publicada.