Autentificación de usuario + cifrado de base de datos con la misma contraseña

3

Estoy trabajando en un proyecto privado donde necesito almacenar los datos financieros de un usuario en una base de datos. Cifraré estos datos usando AES, y usaré scrypt para generar una clave de cifrado AES a partir de una contraseña de usuario más simple.

También quiero poder decirle al usuario si está usando la contraseña correcta al iniciar sesión. La velocidad no es un problema: el programa se ejecutará en el dispositivo del usuario y no en un servidor multiusuario.

Resumiendo: quiero usar una contraseña para cifrar los datos y autenticar a los usuarios.

Puedo ver dos opciones para hacer esto:

  1. Genere un hash SHA-256 a partir de la salida de scrypt, almacene el hash en StoredHash y verifique si SHA256 (scrypt ("contraseña suministrada")) == StoredHash.

  2. Cifre la salida scrypt de la contraseña usando AES en EncryptedScryptOutput usando la salida scrypt como la clave y guárdela, y verifique si scrypt ("contraseña suministrada") == AESdescrypt (decryptionKey = scrypt ("suministrado contraseña "), EncryptedScryptOutput).

Yo (creo que :-) soy consciente de la manera técnica en que se debe hacer esto, utilizando sales y / o vectores iniciales. Mis preguntas son: ¿Estoy seguro de que ambas versiones serán seguras? ¿Diría que una opción es mejor que la otra y por qué?

¡Gracias!

    
pregunta Jelle Veraa 08.11.2012 - 11:53
fuente

2 respuestas

3

Ambas opciones son seguras, pero la primera es preferible.

Su primera propuesta es usar scrypt(password) como clave de cifrado y SHA256(scrypt(password)) como verificador de contraseña. Esto esta bien. Dado que no es computacionalmente posible calcular una preimagen SHA256, no será posible que un atacante calcule la clave de cifrado del verificador de contraseña.

Su segunda propuesta es usar scrypt(password) como clave de cifrado y usar AES(scrypt(password), scrypt(password)) como verificador de contraseñas. Usar un valor como la clave para cifrarse es una forma de hash, por lo que es equivalente a su primera propuesta, excepto que está usando AES (x, x) para hash scrypt(password) en lugar de usar SHA256. Dado que SHA256 es una función hash adecuada y AES (x, x) no es su primera propuesta, es preferible.

    
respondido por el David Wachtfogel 08.11.2012 - 21:45
fuente
7

Por lo que puedo decir, su esquema es el siguiente:

  • Calcule scrypt(pass) y guárdelo como la clave de autenticación en su base de datos.
  • Calcule sha256(scrypt(pass)) y úselo como su clave de cifrado de datos.

El problema con esta técnica es que un atacante con acceso a su base de datos puede simplemente calcular el hash SHA256 de sus hashes Scrypt para obtener las claves de cifrado.

Una mejor solución sería utilizar un segundo hash de cifrado como su clave de cifrado de datos, con una clave sustituta para facilitar los cambios de contraseña fáciles:

  • Genere dos sales ( s1 y s2 ) y almacénelas en texto sin formato.
  • Genere una clave aleatoria criptográficamente segura k - esta es nuestra clave sustituta.
  • Calcule scrypt(pass, s1) y guárdelo como la clave de autenticación en su base de datos.
  • Compute scrypt(pass, s2) y xor k con él. Almacene este valor en su base de datos.
  • Use 'k' como su clave de cifrado de datos.

Al descifrar, calcula scrypt(pass, s2) y xor con el valor de la clave almacenada para recuperar el valor original de k .

Esto lo protege contra los casos en los que se viola la base de datos, y le permite cambiar las contraseñas calculando el valor original de k , y luego guardando eso con el hash scrypt de la nueva contraseña y salt. Tenga en cuenta que si un usuario olvida su contraseña no podrá recuperar los datos.

    
respondido por el Polynomial 08.11.2012 - 13:37
fuente

Lea otras preguntas en las etiquetas