Si obtengo un JWT y puedo decodificar la carga útil, ¿cómo es eso seguro? ¿No podría simplemente tomar el token del encabezado, decodificar y cambiar la información del usuario en la carga útil y enviarlo de vuelta con el mismo secreto codificado correcto?
Sé que deben ser seguros, pero realmente me gustaría entender las tecnologías. ¿Qué me estoy perdiendo?
security
jwt
express-jwt
PixMach
fuente
fuente
md5('original messaged' + secret) != md5('changed message' + secret)
por lo tanto, si alguien cambia el mensaje, puede detectarloRespuestas:
Los JWT pueden ser firmados, cifrados o ambos. Si un token está firmado, pero no está encriptado, 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á.
Responda a su comentario: No estoy seguro si entiendo su comentario de la manera correcta. Solo para estar seguro: ¿conoce y comprende las firmas digitales? Explicaré brevemente una variante (HMAC, que es simétrica, pero hay muchas otras).
Supongamos que Alice quiere enviar un JWT a Bob. Ambos conocen algún secreto compartido. Mallory no conoce ese secreto, pero quiere interferir y cambiar el JWT. Para evitar eso, 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 puede calcular la firma coincidente (que seríaHash(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 firmoHash(content + secret)
. (+ es solo concatenación aquí). Yo uso la función hash SHA256, y la firma que consigo es:330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c
. Ahora es tu turno: desempeña 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 verificar si es correcto.fuente
Puede ir
jwt.io
, pegar su token y leer el contenido. Esto es discordante para mucha gente inicialmente.La respuesta corta es que JWT no se preocupa por el cifrado. Se preocupa por la validación. Es decir, siempre puede obtener la respuesta para "¿Se ha manipulado el contenido de este token"? Esto significa que la manipulación por parte del usuario del token JWT es inútil porque el servidor sabrá y no tendrá en cuenta el token. El servidor agrega una firma basada en la carga útil al emitir un token al cliente. Más tarde verifica la carga útil y la firma coincidente.
La pregunta lógica es ¿cuál es la motivación para no preocuparse por los contenidos cifrados?
La razón más simple es porque supone que este es 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) yhttpOnly
(no puede ser leída por Javascript) y habla con el servidor a través de Un canal encriptado (HTTPS). Una vez que sepa que tiene un canal seguro entre el servidor y el cliente, puede intercambiar JWT de forma segura o lo que quiera.Esto mantiene la cosa simple. Una implementación simple facilita la adopción, pero también permite que cada capa haga lo que hace mejor (deje que HTTPS maneje el cifrado).
JWT no está destinado a almacenar datos confidenciales. Una vez que el servidor recibe el token JWT y lo valida, es libre de buscar la ID de usuario en su propia base de datos para obtener información adicional para ese usuario (como permisos, dirección postal, etc.). Esto mantiene a JWT de tamaño pequeño y evita la fuga accidental de información porque todos saben que no deben guardar datos confidenciales en JWT.
No es muy diferente de cómo funcionan las cookies. Las cookies a menudo contienen cargas útiles sin cifrar. Si está utilizando HTTPS, entonces todo está bien. Si no es así, es recomendable cifrar las cookies confidenciales. No hacerlo significará que es posible un ataque de hombre en el medio: un servidor proxy o ISP lee las cookies y luego las reproduce más tarde fingiendo ser usted. Por razones similares, JWT siempre debe intercambiarse por una capa segura como HTTPS.
fuente
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 solo 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 encriptado 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 firma JWT. Una clave pública verifica que un JWT fue firmado por su clave privada correspondiente. Ninguna otra combinación de teclas puede hacer esta verificación, evitando así los intentos de suplantación. Siga estos dos pasos y podemos garantizar con certeza matemática la autenticidad de un JWT.
Más información: ¿Cómo una clave pública verifica una firma?
fuente
Discutamos desde el principio:
JWT es un enfoque muy moderno, simple y seguro que se extiende a Json Web Tokens. 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 relajantes. Las API de reposo siempre deben estar sin estado, y la alternativa más utilizada para 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 no deberían tener estado y es por eso que soluciones como JWT se hicieron populares y efectivas.
Entonces, ahora sepamos cómo funciona la autenticación con Json Web Tokens. Asumiendo 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, la aplicación luego verifica si el usuario existe y si la contraseña es correcta, entonces la aplicación generará un Json Web Token único solo para ese usuario.
El token se crea usando 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 un almacenamiento local.
Así, el usuario se autentica y básicamente inicia sesión en nuestra aplicación sin dejar ningún estado en el servidor.
Por lo tanto, el servidor no sabe qué usuario ha iniciado sesión realmente, pero, por supuesto, el usuario sabe que ha iniciado sesión porque tiene un Json Web Token válido, que es un poco como un pasaporte para acceder a partes protegidas de la aplicación.
Así que de nuevo, solo para asegurarte de que tienes la idea. Un usuario inicia sesión tan pronto como recupera su Json Web Token válido único que no se guarda en ningún lugar del servidor. Y, por lo tanto, este proceso es completamente apátrida.
Luego, cada vez que un usuario desea 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 un poco como mostrar su pasaporte para obtener acceso a esa ruta.
Una vez que la solicitud llegue 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, de lo contrario, habrá ser un error diciéndole al usuario que no tiene permitido acceder a ese recurso.
Toda esta comunicación debe realizarse a través de https, por lo que es seguro Http cifrado para evitar que cualquiera pueda acceder a contraseñas o Json Web Tokens. Solo entonces tenemos un sistema realmente seguro.
Entonces, un Json Web Token parece parte izquierda de esta captura de pantalla que fue tomada del depurador JWT en jwt.io Así que, esencialmente, 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 solo texto sin formato que se codificarán, pero no se cifrarán.
Por lo tanto, cualquiera podrá decodificarlos y leerlos , no podemos almacenar ningún dato confidencial aquí. Pero eso no es un problema en absoluto porque en la tercera parte, así que en la firma, es donde las cosas realmente se ponen 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, solo estos datos más el secreto pueden crear esta firma, ¿de acuerdo? Luego, junto con el encabezado y la carga útil, estas firmas forman el JWT, que luego se envía al cliente.
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 del token. Entonces, nuevamente, este paso de verificación verificará si ningún tercero realmente alteró el encabezado o la carga 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 se guarda en el servidor, básicamente crea una firma de prueba.
Pero la firma original que se generó cuando se creó el JWT aún 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.
Porque si hubieran sido modificados, entonces la firma de la prueba tendría que ser diferente. Por lo tanto, en este caso donde no ha habido alteración de los datos, podemos autenticar al usuario. Y, por supuesto, si las dos firmas son realmente diferentes, entonces significa que alguien manipuló los datos. Por lo general, tratando de 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 tanto, la firma original nunca corresponderá a los datos manipulados. Y por lo tanto, la verificación siempre fallará en este caso. Y esa es la clave para hacer que todo este sistema funcione. Es la magia que hace que JWT sea tan simple, pero también extremadamente poderoso.
fuente
Solo la clave privada de JWT, que está en su servidor, descifrará el JWT cifrado. Quienes conozcan la clave privada podrán descifrar el JWT cifrado.
Oculte la clave privada en una ubicación segura en su servidor y nunca le diga a nadie la clave privada.
fuente
Para las personas que no pueden pagar costosas consultas de bases de datos como yo, una opción para mantener datos confidenciales (privilegios de usuario, etc.) es que, al generar el JWT, puede cifrar estos datos y adjuntarlos al token JWT. (Mantenga la clave de cifrado en el backend)
Cuando desee leer la información confidencial, puede enviar el token JWT al backend y descifrarlo y recuperar la información. De esta manera, no tiene que hacer búsquedas de base de datos o tener la información confidencial desnuda en la interfaz a través del token JWT
fuente
Sugeriría echar un vistazo a JWE utilizando algoritmos especiales que no están presentes en jwt.io para descifrar
Enlace de referencia: https://www.npmjs.com/package/node-webtokens
Esta respuesta puede ser demasiado tarde o puede que ya hayas descubierto el camino, pero aún así, sentí que sería útil para ti y para los demás también.
Un ejemplo simple que he creado: https://github.com/hansiemithun/jwe-example
fuente