Si puedes decodificar JWT, ¿cómo son seguros?

Resuelto Z2VvZ3Vp asked hace 10 años • 9 respuestas

Si obtengo un JWT y puedo decodificar la carga útil, ¿cómo es eso seguro? ¿No podría simplemente sacar el token del encabezado, decodificar y cambiar la información del usuario en la carga útil y enviarlo de regreso con el mismo secreto codificado correcto?

Sé que deben ser seguros, pero realmente me gustaría entender las tecnologías. ¿Qué me estoy perdiendo?

Z2VvZ3Vp avatar Dec 05 '14 01:12 Z2VvZ3Vp
Aceptado

Los JWT pueden estar firmados, cifrados o ambos. Si un token está firmado, pero no cifrado, todos pueden leer su contenido, pero cuando no conoce la clave privada, no puede cambiarla. De lo contrario, el receptor notará que la firma ya no coincidirá.

Respuesta a tu comentario: No estoy seguro de haber entendido tu comentario correctamente. Sólo para estar seguro: ¿conoce y comprende las firmas digitales? Sólo explicaré brevemente una variante (HMAC, que es simétrica, pero hay muchas otras).

Supongamos que Alice quiere enviarle un JWT a Bob. Ambos conocen algún secreto compartido. Mallory no conoce ese secreto, pero quiere interferir y cambiar el JWT. Para evitarlo, Alice calcula Hash(payload + secret)y agrega esto como firma.

Al recibir el mensaje, Bob también puede calcular Hash(payload + secret)para verificar si la firma coincide. Sin embargo, si Mallory cambia algo en el contenido, no podrá calcular la firma coincidente (que sería Hash(newContent + secret)). Ella no conoce el secreto y no tiene forma de descubrirlo. Esto significa que si ella cambia algo, la firma ya no coincidirá y Bob simplemente ya no aceptará el JWT.

Supongamos que le envío el mensaje a otra persona {"id":1}y lo firmo con Hash(content + secret). (+ es solo una concatenación aquí). Utilizo la función SHA256 Hash y la firma que obtengo es: 330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c. Ahora te toca a ti: juega el papel de Mallory e intenta firmar el mensaje {"id":2}. No puedes porque no sabes qué secreto usé. Si supongo que el destinatario conoce el secreto, PUEDE calcular la firma de cualquier mensaje y comprobar si es correcta.

Misch avatar Dec 04 '2014 18:12 Misch

Discutamos desde el principio:

JWT es un enfoque muy moderno, simple y seguro que se extiende a los Json Web Tokens. Los Json Web Tokens son una solución sin estado para la autenticación. Por lo tanto, no es necesario almacenar ningún estado de sesión en el servidor, lo que por supuesto es perfecto para API tranquilas. Las API Restful siempre deben ser sin estado, y la alternativa más utilizada a la autenticación con JWT es simplemente almacenar el estado de inicio de sesión del usuario en el servidor mediante sesiones. Pero, por supuesto, no sigue el principio que dice que las API relajantes deben ser sin estado y es por eso que soluciones como JWT se volvieron populares y efectivas.

Ahora sepamos cómo funciona realmente la autenticación con Json Web Tokens. Suponiendo que ya tenemos un usuario registrado en nuestra base de datos. Entonces, el cliente del usuario comienza haciendo una solicitud de publicación con el nombre de usuario y la contraseña, luego la aplicación verifica si el usuario existe y si la contraseña es correcta, luego la aplicación generará un token web Json único solo para ese usuario.

El token se crea utilizando una cadena secreta que se almacena en un servidor . A continuación, el servidor envía ese JWT al cliente, que lo almacenará en una cookie o en el almacenamiento local. ingrese la descripción de la imagen aquí

Así, el usuario se autentica y básicamente inicia sesión en nuestra aplicación sin salir de ningún estado en el servidor.

Entonces, el servidor no sabe qué usuario realmente inició sesión, pero, por supuesto, el usuario sabe que inició sesión porque tiene un Json Web Token válido, que es como un pasaporte para acceder a partes protegidas de la aplicación.

De nuevo, solo para asegurarnos de que entendiste la idea. Un usuario inicia sesión tan pronto como recupera su token web Json válido único que no se guarda en ninguna parte del servidor. Por lo tanto, este proceso es completamente apátrida.

Luego, cada vez que un usuario quiera acceder a una ruta protegida como sus datos de perfil de usuario, por ejemplo. Envía su Json Web Token junto con una solicitud, por lo que es como mostrar su pasaporte para acceder a esa ruta.

Una vez que la solicitud llega al servidor, nuestra aplicación verificará si el Json Web Token es realmente válido y si el usuario es realmente quien dice ser, entonces los datos solicitados se enviarán al cliente y, si no, habrá será un error diciéndole al usuario que no tiene permiso para acceder a ese recurso. ingrese la descripción de la imagen aquí

Toda esta comunicación debe realizarse a través de https, por lo que se debe proteger Http cifrado para evitar que cualquiera pueda acceder a contraseñas o tokens web Json. Sólo entonces tendremos un sistema realmente seguro.

ingrese la descripción de la imagen aquí

Entonces, un Json Web Token parece la parte izquierda de esta captura de pantalla que fue tomada del depurador JWT en jwt.io. Básicamente, es una cadena de codificación compuesta de tres partes. El encabezado, la carga útil y la firma Ahora el encabezado son solo algunos metadatos sobre el token en sí y la carga útil son los datos que podemos codificar en el token, cualquier dato que realmente queramos. Entonces, cuantos más datos queramos codificar aquí, mayor será el JWT. De todos modos, estas dos partes son simplemente texto sin formato que se codificará, pero no se cifrará.

Para que cualquiera pueda decodificarlos y leerlos , no podemos almacenar ningún dato confidencial aquí. Pero eso no es un problema en absoluto porque en la tercera parte, es decir, en la firma, es donde las cosas se ponen realmente interesantes. La firma se crea utilizando el encabezado, la carga útil y el secreto que se guarda en el servidor.

Y todo este proceso se llama firmar el Json Web Token . El algoritmo de firma toma el encabezado, la carga útil y el secreto para crear una firma única. Entonces sólo estos datos más el secreto pueden crear esta firma, ¿de acuerdo? Luego, junto con el encabezado y la carga útil, esta firma forma el JWT, que luego se envía al cliente. ingrese la descripción de la imagen aquí

Una vez que el servidor recibe un JWT para otorgar acceso a una ruta protegida, necesita verificarlo para determinar si el usuario realmente es quien dice ser. En otras palabras, verificará si nadie cambió el encabezado y los datos de carga útil del token. Nuevamente, este paso de verificación verificará si ningún tercero realmente alteró el encabezado o la carga útil del Json Web Token.

Entonces, ¿cómo funciona realmente esta verificación? Bueno, en realidad es bastante sencillo. Una vez que se recibe el JWT, la verificación tomará su encabezado y carga útil y, junto con el secreto que aún está guardado en el servidor, básicamente creará una firma de prueba.

Pero la firma original que se generó cuando se creó el JWT por primera vez todavía está en el token, ¿verdad? Y esa es la clave de esta verificación. Porque ahora todo lo que tenemos que hacer es comparar la firma de prueba con la firma original. Y si la firma de prueba es la misma que la firma original, significa que la carga útil y el encabezado no se han modificado. ingrese la descripción de la imagen aquí

Porque si se hubieran modificado, entonces la firma de la prueba tendría que ser diferente. Por tanto, en este caso en el que no haya habido alteración de los datos, podremos autentificar al usuario. Y, por supuesto, si las dos firmas son realmente diferentes, entonces significa que alguien manipuló los datos. Generalmente intentando cambiar la carga útil. Pero ese tercero que manipula la carga útil, por supuesto, no tiene acceso al secreto, por lo que no puede firmar el JWT. Por lo que la firma original nunca se corresponderá con los datos manipulados. Y por tanto, la verificación siempre fallará en este caso. Y esa es la clave para que todo este sistema funcione. Es la magia lo que hace que JWT sea tan simple, pero también extremadamente poderoso.

Rafiq avatar May 29 '2020 21:05 Rafiq

Puedes ir a jwt.io, pegar tu token y leer el contenido. Al principio, esto resulta desconcertante para mucha gente.

La respuesta corta es que JWT no se ocupa del cifrado. Se preocupa por la validación. Es decir, ¿siempre puede obtener la respuesta a "¿Se ha manipulado el contenido de este token"? Esto significa que la manipulación del token JWT por parte del usuario es inútil porque el servidor conocerá el token y lo ignorará. El servidor agrega una firma basada en la carga útil al emitir un token al cliente. Posteriormente verifica la carga útil y la firma coincidente.

La pregunta lógica es ¿cuál es la motivación para no preocuparse por contenidos cifrados?

  1. La razón más simple es porque supone que se trata de un problema resuelto en su mayor parte. Si se trata de un cliente como el navegador web, por ejemplo, puede almacenar los tokens JWT en una cookie que secure(no se transmite a través de HTTP, solo a través de HTTPS) y httpOnly(no puede leerse mediante Javascript) y se comunica con el servidor a través de un canal cifrado (HTTPS). Una vez que sepa que tiene un canal seguro entre el servidor y el cliente, podrá intercambiar JWT de forma segura o cualquier otra cosa que desee.

  2. Esto simplifica las cosas. Una implementación simple facilita la adopción, pero también permite que cada capa haga lo que mejor sabe hacer (dejar que HTTPS maneje el cifrado).

  3. JWT no está destinado a almacenar datos confidenciales. Una vez que el servidor recibe el token JWT y lo valida, puede buscar la identificación del usuario en su propia base de datos para obtener información adicional para ese usuario (como permisos, dirección postal, etc.). Esto mantiene el tamaño de JWT pequeño y evita la fuga de información involuntaria porque todos saben que no se deben guardar datos confidenciales en JWT.

No es muy diferente de cómo funcionan las propias cookies. Las cookies suelen contener cargas útiles no cifradas. Si estás usando HTTPS entonces todo está bien. Si no es así, es recomendable cifrar las cookies confidenciales. No hacerlo significará que es posible un ataque de intermediario: un servidor proxy o ISP lee las cookies y luego las reproduce haciéndose pasar por usted. Por razones similares, JWT siempre debe intercambiarse a través de una capa segura como HTTPS.

aleemb avatar Feb 22 '2017 09:02 aleemb

El contenido de un token web json (JWT) no es inherentemente seguro, pero hay una función incorporada para verificar la autenticidad del token. Un JWT son tres hashes separados por puntos. El tercero es la firma. En un sistema de clave pública/privada, el emisor firma la firma del token con una clave privada que sólo puede ser verificada por su clave pública correspondiente.

Es importante comprender la distinción entre emisor y verificador. El destinatario del token es responsable de verificarlo.

Hay dos pasos críticos para usar JWT de forma segura en una aplicación web: 1) enviarlos a través de un canal cifrado y 2) verificar la firma inmediatamente después de recibirla. La naturaleza asimétrica de la criptografía de clave pública hace posible la verificación de firmas JWT. Una clave pública verifica que un JWT haya sido firmado por su clave privada correspondiente. Ninguna otra combinación de claves puede realizar esta verificación, evitando así intentos de suplantación. Siga estos dos pasos y podremos garantizar con certeza matemática la autenticidad de un JWT.

Más lectura: ¿ Cómo verifica una clave pública una firma?

ThisClark avatar Apr 19 '2017 13:04 ThisClark