Proporcionaré una versión ligeramente diferente de esto.
Siempre guardo la sal mezclada con el hash de contraseña salada.
Por ejemplo, colocaré la primera mitad de la sal antes del hash salado de la contraseña, y la última mitad de la sal después del hash salado de la contraseña. La aplicación conoce este diseño, por lo que puede obtener estos datos y obtener el hash de sal y contraseña salada.
Mi razonamiento para este enfoque:
Si los datos de contraseña / hash se ven comprometidos y caen en manos de un atacante, el atacante no sabrá cuál es la sal de mirar los datos. De esta manera, un atacante prácticamente no puede realizar un ataque de fuerza bruta para obtener una contraseña que coincida con el hash, ya que no conoce el hash para empezar y no tiene forma de saber qué partes de los datos son partes de la sal, o partes del hash de contraseña salada (a menos que él conozca la lógica de autenticación de su aplicación ).
Si el hash de contraseña salada se almacena tal cual, entonces se puede realizar un ataque de fuerza bruta para obtener una contraseña que cuando se salada y hash produce los mismos datos que el hash de contraseña salada.
Sin embargo, por ejemplo, incluso si el hash de la contraseña salada se almacenó tal cual, pero se colocó previamente con un solo byte aleatorio, siempre que el atacante no sepa que este primer byte debe descartarse, esto también aumentaría la dificultad de ataque Su aplicación debería descartar el primer byte de los datos cuando se utiliza para autenticar a su usuario.
La conclusión de esto ...
1) Nunca almacene los datos que utiliza su aplicación de autenticación en su forma exacta.
2) Si es posible, mantenga su lógica de autenticación en secreto para mayor seguridad.
Ve un paso más allá ...
Si no puede mantener en secreto la lógica de autenticación de su aplicación, mucha gente sabe cómo se almacenan sus datos en la base de datos. Y suponga que ha decidido almacenar el hash de contraseña salada mezclado junto con la sal, con algo de sal que antecede al hash de contraseña salada, y el resto de la sal añadiéndola.
Al generar la sal al azar, también puede decidir al azar qué proporción de su sal almacenará antes / después del hash de contraseña salada.
Por ejemplo, genera una sal aleatoria de 512 bytes. Agregue la sal a su contraseña y obtenga el hash SHA-512 de su contraseña salada. También genera un número entero aleatorio 200. Luego almacena los primeros 200 bytes de la sal, seguidos del hash de la contraseña salada, seguido del resto de la sal.
Al autenticar la entrada de contraseña de un usuario, su aplicación pasará la cadena y asumirá que el primer 1 byte de los datos es el primer 1 byte de la sal, seguido del hash salado. Este pase fallará. La aplicación continuará utilizando los primeros 2 bytes de los datos como los primeros 2 bytes de la sal, y se repetirá hasta que se encuentre un resultado positivo después de usar los primeros 200 bytes como los primeros 200 bytes de la sal. Si la contraseña es incorrecta, la aplicación continuará probando todas las permutaciones hasta que no se encuentre ninguna.
Los pros de este enfoque:
Mayor seguridad: incluso si se conoce su lógica de autenticación, se desconoce la lógica exacta en tiempo de compilación. Es prácticamente imposible realizar un ataque de fuerza bruta, incluso con el conocimiento de la lógica exacta. El aumento de la longitud de la sal aumentará aún más la seguridad.
Los contras de este enfoque:
Dado que la lógica exacta se infiere en tiempo de ejecución, este enfoque requiere mucha CPU. Cuanto más larga sea la sal, más intensivo será este enfoque.
La autenticación de contraseñas incorrectas implicará el mayor costo de CPU. Esto puede ser contraproducente para solicitudes legítimas, pero aumenta la seguridad contra los atacantes.
Este enfoque se puede implementar de varias maneras y se puede hacer aún más seguro mediante el uso de sales de ancho variable y / o hashes de contraseña salada.