¿Almacenamiento / uso adecuado de las contraseñas con sal?

3

Si una sal no se almacena junto con la contraseña de hash en la base de datos, ¿es posible que la contraseña esté incluida?

Lo pregunto porque en un sistema en el que estoy trabajando solo hay una columna de contraseña, pero cuando reviso el código, parece que quien haya escrito esto está intentando saltear la contraseña.

Por lo que entendí, las contraseñas / sales se deben almacenar como a continuación:

email         | password (hashed)        | salt (not hashed)
[email protected] | de898928393a893sfe7f98s7 | S#ne3

Entonces, cuando un usuario se registre con su contraseña ("froggy" en el ejemplo a continuación) iría de esta forma:

//Generate salt (S#ne3 for this example)
//encrypt ("froggy" + "S#ne3")
//Save encrypted pw + salt to database AND save unencrypted salt to database

Luego, cuando el usuario intentara iniciar sesión con "froggy", haría algo como esto:

//Query database for user's record.  Store this in curUser object
//Check to see if the following match: encrypt("froggy" + curUser.salt) == curUser.password

¿Esto suena bien? Si estoy en lo cierto, ¿es seguro asumir que las contraseñas de este sistema no están sujetas a sal?

    
pregunta Abe Miessler 17.08.2013 - 01:03
fuente

3 respuestas

3

En primer lugar, las contraseñas se almacenan de forma segura (suponiendo que el algoritmo de hashing utilizado sea seguro) ya que la única cosa de texto simple es la sal que tiene que ser texto simple, su único propósito es evitar que el hash final sea hash(password) ya que eso permitiría el uso de tablas de arco iris precalculadas que asignan hashes a las contraseñas.

Sin embargo, la forma de almacenarlas usando dos columnas separadas no es óptima. Aunque es algo fácil de usar cuando solo se pasa la contraseña de sal y de texto sin formato a una función hash, la mayoría de las bibliotecas de hash de contraseña usan un mejor esquema. Echemos un vistazo a bcrypt (o más bien a sus enlaces python por simplicidad) que usa el mismo esquema que crypt(3) hace.

>>> import bcrypt
>>> bcrypt.gensalt()
'$2a$12$xYkBJKIdbmAZlhpl96dopO'
>>> bcrypt.hashpw('foo', '$2a$12$xYkBJKIdbmAZlhpl96dopO')
'$2a$12$xYkBJKIdbmAZlhpl96dopOJug5oZcp4tVWJPug/xMdFQzVMJDOvH6'
>>> bcrypt.hashpw('foo', '$2a$12$xYkBJKIdbmAZlhpl96dopOJug5oZcp4tVWJPug/xMdFQzVMJDOvH6')
'$2a$12$xYkBJKIdbmAZlhpl96dopOJug5oZcp4tVWJPug/xMdFQzVMJDOvH6'

Como puede ver, el hash resultante consta de varias partes . Primero, el 2a que indica el algoritmo , luego el "costo" utilizado por el algoritmo, luego los 22 caracteres sal (en texto plano), luego el hash real.

La ventaja de esto es que la verificación de la contraseña se puede hacer usando la misma función que usas para hacer hash: simplemente pasas la cadena de hash completa como la sal y luego verificas si devuelve la misma cadena. Otra ventaja más relevante es el hecho de que al almacenarlo de esta manera, puede escribir fácilmente una función para manejar varios algoritmos de hash al verificar el primer campo. Esto es relevante cuando tiene que lidiar con contraseñas heredadas que fueron ocultadas, por ejemplo. utilizando MD5 o SHA-1.

    
respondido por el ThiefMaster 17.08.2013 - 13:09
fuente
3

Algunas funciones de hash de contraseñas tradicionalmente codifican la sal y la salida de hash como una única cadena, por lo que la sal está ahí, pero no aparece en la base de datos como una columna específica. La mayoría de las bibliotecas bcrypt hacen eso. Este podría ser el caso de su sistema.

Además, la sal podría estar implícita (por ejemplo, computada como la concatenación del nombre de usuario y una ID de fila, o algo así).

    
respondido por el Thomas Pornin 17.08.2013 - 02:01
fuente
2

La sal debe ser conocida para verificar la contraseña hash. No hay razón para no almacenarlo con el hash en la base de datos, ya que es perfectamente seguro que sea información pública. Su propósito es solo evitar que se usen los hash precomputadores para encontrar rápidamente contraseñas inseguras.

    
respondido por el AJ Henderson 17.08.2013 - 01:10
fuente

Lea otras preguntas en las etiquetas