Estoy implementando un servicio REST que requiere autenticación. No puedo almacenar ningún estado por usuario (como un token generado aleatoriamente) porque mi servicio no tiene acceso directo a una base de datos, solo a otro servicio backend.
La solución que se me ocurrió es crear un token web JSON ( JWT ) Cuando el usuario se autentica. El conjunto de notificaciones JWT contiene el ID de usuario en el campo Asunto ("sub"). Luego, el servidor cifra el conjunto de notificaciones directamente ("alg": "dir") utilizando AES GCM con una clave de 256 bits ("enc": "A256GCM") creando un JWE . La clave se genera una vez cuando se inicia el servicio y se almacena en la memoria.
Para autenticarse, el cliente envía el nombre de usuario / contraseña y el servidor responde con el token descrito anteriormente. El cliente envía ese token con cada solicitud posterior.
Cuando el cliente envía el token con las solicitudes subsiguientes, el servidor lo descifra mediante la clave y asume que la ID de usuario en el campo "sub" es la ID del usuario actual, sin más comprobaciones de autenticación. La caducidad del token se maneja mediante el campo "exp" en el conjunto de reclamaciones JWT.
La conexión entre el cliente y el servidor usará SSL / TLS, por lo que el token no tendrá fugas.
Estoy usando esta biblioteca para crear y leer JWT, ya que no confío en mí mismo para escribir el código de criptografía correcto .
Mis preguntas:
- ¿Es seguro el enfoque anterior? ¿Puede un atacante hacerse pasar por otro usuario manipulando el token?
- ¿Es el enfoque demasiado complicado? ¿El uso de MAC (en otras palabras: JWS ) en lugar del cifrado, tiene la misma seguridad? (o posiblemente más, ya que es más simple y hay menos posibilidades de cometer un error). No hay nada particularmente secreto en el conjunto de reclamaciones de JWT, y el usuario que conoce su propia identificación no importa.
- ¿Es mi elección del algoritmo JWE y el cifrado apropiado?
- Para el "alg" de JWE, la biblioteca que estoy usando soporta el cifrado directo (usando la clave directamente para cifrar el conjunto de reclamaciones) y RSA (generando una nueva clave para cifrar el conjunto de reclamaciones para cada token, y cifrando el clave con una clave pública RSA). Elegí el primero porque es más fácil generar una clave simétrica que una clave RSA.
- Para la "enc" de JWE, la biblioteca admite AES GCM y AES CBC HMAC SHA2 (con varias longitudes de bits). Elegí GCM arbitrariamente.