TL; DR Dado que toda la información de estado de un navegador web es accesible para un usuario (potencialmente hostil), ¿cómo puede considerarse segura la autenticación de respuesta-desafío entre el navegador y el servidor?
La versión más larga
Estoy desarrollando una aplicación web y quiero implementar sockets web para la comunicación entre el cliente y el servidor. Estoy considerando la implementación de un enrutador WAMP y estoy tratando de entender los modos de autenticación con un sistema como este.
El protocolo WAMP permite la autenticación de desafío-respuesta (CRA). La forma en que lo entiendo (y por favor me corrige si tengo este error), cuando un cliente realiza una solicitud de conexión, el servidor envía un desafío. Luego, el cliente encripta el desafío usando una clave secreta que se comparte entre el cliente y el servidor y la devuelve. El servidor verifica la versión encriptada del cliente y, si se cifró correctamente, permite el acceso. El uso de un secreto compartido permite al servidor saber que la solicitud provino de un cliente autorizado.
Esto conduce a pregunta # 1 : el código Javascript enviado al navegador debe contener el secreto compartido. Entonces el secreto compartido no es muy secreto, ¿verdad? Entonces, ¿cómo podemos considerar esto como un método seguro de autenticación?
Al pensar en esta pregunta, he encontrado una solución que creo que podría resolver el problema.
Nota importante: todas las conexiones se protegerán a través de TLS.
Así es como podría funcionar mi sistema de autenticación:
-
el usuario inicia sesión a través del método de autenticación normal basado en formularios
-
el servidor genera una clave de autenticación y un secreto, y pasa esos valores al cliente como parte de la página HTML. La clave y el secreto se generan a través de un método criptográficamente seguro.
-
el cliente luego inicia la conexión websocket. Esto comienza la secuencia de autenticación de desafío-respuesta, utilizando la clave y el secreto generado por el servidor
-
el servidor se autentica, usando la tecla & secreto, y todo está bien.
La clave aquí es el uso único de los valores clave y secreto. Si cambian periódicamente, entonces no hay forma de que un atacante pueda generar un par clave / secreto o usar uno que haya guardado de una visita anterior.
Lo que me lleva a la pregunta # 2 : ¿es este un esquema de autenticación adecuado?
Y finalmente, pregunta # 3 : suponiendo que el esquema de autenticación descrito anteriormente sea adecuado, ¿con qué frecuencia deberían cambiar los valores clave / secreto? Estoy pensando que definitivamente debería cambiar cada vez que el usuario inicia sesión, y también debería expirar después de que hayan transcurrido 6-8 horas. ¿Pensamientos?