Sí, puede almacenarlo en un solo campo, y muchas bases de datos / aplicaciones almacenan el hash + sal en un solo campo / archivo, etc.
El más famoso es Linux (que no es una base de datos), que almacena el hash en el archivo / etc / shadow con el formato:
"$ id $ salt $ hashed", la forma imprimible de un hash de contraseña como se produce
por crypt (C), donde "$ id" es el algoritmo utilizado. (En GNU / Linux, "$ 1 $"
significa MD5, "$ 2a $" es Blowfish, "$ 2y $" es Blowfish (correcto
manejo de caracteres de 8 bits), "$ 5 $" es SHA-256 y "$ 6 $" es SHA-512, [4]
otros Unix pueden tener diferentes valores, como NetBSD.
(fuente: enlace )
La sal no debe ser secreta (o al menos no más secreta que el hash). Su propósito principal es hacer que los ataques de fuerza bruta sean mucho más difíciles, ya que el atacante tiene que usar una sal diferente para cada usuario individual.
Pero su pregunta tiene más matices, porque no solo está preguntando acerca de las sales, sino también de los parámetros. Cosas como el algoritmo de hash, el recuento de iteraciones y la sal. En cualquier caso, no almacene esto en el código, todavía pertenecen a la base de datos.
Imagina que tienes muchos usuarios y has usado SHA1 como algoritmo de hash. Entonces el campo de su base de datos sería algo como SHA1: SALT: HASH .
Si quisiera actualizar su base de datos a BCRYPT, ¿cómo haría esto?
Por lo general, implementaría algún código para que cuando un usuario inicie sesión, verifique la contraseña y, si es válida, vuelva a codificar la contraseña con un algoritmo más nuevo. Ahora el campo para el usuario se ve así: BCRYPT: SALT: HASH .
Pero entonces algunos usuarios estarán en SHA1 y otros en BCRYPT, y dado que esto es a nivel de usuario, necesita los parámetros que indican a su código qué usuarios están en la base de datos.
En resumen, almacenar los parámetros y el hash en un solo campo está bien, pero dividirlos por cualquier motivo (eficiencia, código más sencillo, etc.) también está bien. Lo que no está bien es almacenar esto en su código :)
TL:DR
Troy Hunt publicó recientemente un podcast que sugiere que, en lugar de migrar a BCRYPT de la manera anterior, es más efectivo simplemente tomar todos los hashes SHA1 que se encuentran actualmente en la base de datos, y hacerlos usando BCRYPT.
Efectivamente BCRYPT(SHA1(clear_password))
Cuando un usuario inicia sesión,
BCRYPT(SHA1(clear_password)) == <db_field>
De esta manera, todos los usuarios de la plataforma se actualizan a la vez, y no tiene una base de datos con múltiples formatos de hash para contraseñas. Muy limpio y muy bonito.
Creo que esta idea tiene mucho sentido, pero aunque todos migran a la vez, no es instantáneo. A menos que esté dispuesto a aceptar algún tiempo de inactividad en la aplicación (mientras vuelve a aplicar todas las contraseñas), seguirá habiendo un pequeño espacio de tiempo en el que algunos usuarios están en BCRYPT y otros en SHA1, por lo tanto, su base de datos todavía debe almacenar el parámetros del algoritmo de hash, y su código se ejecutaría en función de él.