Alimentar PBKDF2 a la creación del verificador SRP

4

Hay un juego más antiguo que solo utiliza UDP para comunicarse, y quería agregar autenticación de contraseña al juego para facilitar cosas como puntos de experiencia y clasificaciones. Para este fin, decidí ir con una implementación de SRP-6a comunicada a través de UDP utilizando una extensión del protocolo de juego existente, y terminé usando cocagne / csrp en el lado del cliente del juego, canalizado a través del servidor del juego, y mozilla / node-srp en el lado del servidor de autenticación, ligeramente modificado para producir la respuesta de seguimiento HAMK compatible con csrp.

Hasta ahora ha funcionado razonablemente bien, sin embargo, no soy un fanático de cómo se almacena el verificador en reposo, ya que parece que en el proceso de cálculo de x las entradas solo se incluyen una vez antes de convertirse en el verificador v , consulte aquí . He sugerido que cambiemos esta función de biblioteca para adaptarla a nuestras necesidades (ya que es razonablemente pequeña y ya está en el árbol) y usamos algo como PBKDF2. Sin embargo, estoy recibiendo una respuesta (comprensible) de otro desarrollador acerca de tocar el código de esta naturaleza, buenas intenciones y todo eso.

En cambio, se sugirió que tal vez la propia contraseña del usuario se someta al hash PBKDF2 antes de pasarla como contraseña para la creación del verificador y las funciones de desafío del usuario. De esa manera, no tenemos que modificar ningún código en la propia biblioteca csrp. ¿Es este un enfoque válido? ¿O hay otra trampa para osos esperando para atraparnos si hacemos esto?

Para lo que vale, el documento de protocolo completo es here , así como si estoy haciendo cualquier otro tipo de error, sería bueno saberlo.

    
pregunta AlexMax 20.11.2014 - 00:50
fuente

1 respuesta

4

La contraseña en SRP es en realidad un secreto compartido de (posiblemente) baja entropía . Puede ser la "contraseña" tal como la entiende el usuario humano, o cualquier cosa que se derive determinísticamente de la contraseña. En su caso, sí, usar una función de hashing de contraseña como PBKDF2 es un enfoque válido. Tiene las siguientes advertencias:

  • PBKDF2, como bcrypt y otras funciones de hash de buena contraseña, requiere un salt . La sal es muy importante. Sin la sal, el atacante podría optimizar los ataques en gran medida; a saber, tendría que pagar por el paso PBKDF2 para un solo usuario (si tiene varios hashes almacenados para que varios usuarios los resquíen) El punto aquí es que el cliente y el servidor deben usar la misma sal para un usuario determinado, por lo que el cliente debe conocer esa sal de alguna manera. Pero la sal debe seguir siendo específica para cada usuario (y cambiarse cada vez que el usuario también cambie su contraseña), por lo que no puede simplemente codificarla en el código del cliente.

    Por lo tanto, debe almacenar la sal por usuario en el servidor, y para transmitirla al cliente como un paso de autenticación inicial. En SRP, el cliente primero envía un mensaje que contiene el nombre de usuario ( I ) y un valor que no depende de la contraseña ( A ). El servidor responde con la sal específica del usuario ( s ) y otro mensaje ( B ). Debe enviar también en ese mensaje de servidor a cliente el extra de sal necesario para PBKDF2.

    Alternativamente, puede reemplazar el paso de hashing en SRP con PBKDF2, pero esto implica modificar el protocolo y las bibliotecas de implementación, lo que probablemente no sea una buena idea. Es más simple y más seguro agregar un paso PBKDF2 adicional.

    Es tentador reutilizar el mismo sal que el especificado por SRP (el llamado s en la especificación del protocolo). Aunque esto parece criptográficamente seguro aquí (los dos usos de la sal son algo "separados" con todo el PBKDF2 entre ellos), se sabe que este tipo de cosas es una cuestión de sutileza, y, nuevamente, tener una sal extra e independiente es la clave. Método seguro y cauteloso.

  • PBKDF2 emplea muchas iteraciones para ralentizar a los atacantes. Pero también ralentiza a los usuarios normales, por lo que no puede aumentar el número de iteraciones tan alto como desee. Debe configurar todo lo alto que pueda tolerar, dada la carga y el poder computacional de las computadoras involucradas, y los límites de la paciencia del usuario.

    En el caso de la integración con SRP, como con cualquier otro protocolo de PAKE , el costo más alto de la contraseña de hashing está en el lado del cliente. Por lo tanto, el recuento de iteraciones apropiado depende del equipo cliente . Si tiene varios clientes, debe adaptarse a la computadora menos poderosa que aún se supone que debe poder conectarse. Este punto es especialmente crucial para el cliente basado en la Web, con JavaScript, porque JavaScript es muy débil para los cálculos en bruto, lo que limita gravemente el número de iteraciones que puede tolerar. En su caso, el código del cliente utiliza una biblioteca de C, por lo que puede tener algo de músculo del lado del cliente, pero como está trabajando con un "juego antiguo", debe considerar que el cliente puede ser una "máquina más antigua", posiblemente una " anciano máquina". Hay algunos pervertidos por ahí que aún cuidan algunas computadoras i486.

  • Puedes considerar usar bcrypt en lugar de PBKDF2; bcrypt es posiblemente más fuerte contra los atacantes con GPU.

respondido por el Tom Leek 20.11.2014 - 02:31
fuente

Lea otras preguntas en las etiquetas