Salar su contraseña: ¿mejores prácticas?

162

Siempre he tenido curiosidad ... ¿Qué es mejor al salar una contraseña para el hash: prefijo o postfix? ¿Por qué? ¿O importa, siempre y cuando sal?

Para explicar: Todos (con suerte) ya sabemos que debemos sacar una contraseña antes de usarla para guardarla en la base de datos [ Editar: para que pueda evitar cosas como lo que le sucedió a Jeff Atwood recientemente ]. Por lo general, esto se hace concatenando la sal con la contraseña antes de pasarla por el algoritmo de hash. Pero los ejemplos varían ... Algunos ejemplos anteponen la sal antes de la contraseña. Algunos ejemplos agregan la sal después de la contraseña. Incluso he visto algunos que intentan poner la sal en el medio.

Entonces, ¿cuál es el mejor método y por qué? ¿Hay algún método que disminuya la posibilidad de una colisión de hash? Mi Google no ha arrojado un análisis decente sobre el tema.

Editar: ¡ Grandes respuestas amigos! Lo siento, solo pude elegir una respuesta. :)

Randolpho
fuente
1
@Jaccco: entrada impresionante. ¡Gracias!
Randolpho
3
La mejor práctica es usar una función criptográfica que haga la salazón por usted, usando PBKDF2 (el estándar), bcrypt o incluso scrypt. Gracias a Stephen por señalar eso.
Maarten Bodewes
1
Casi todas las construcciones de hashing de contraseñas estándar se encargan de combinar sal y contraseña, por lo que no debe preocuparse por esto. Si no utiliza un hash de contraseña estándar, migre a uno.
CodesInChaos
1
@Omu Mala recomendación. 1) Una sola iteración de SHA-1 es demasiado rápida, debe usar al menos 10000, e incluso eso es bastante débil. 2) La sal predeterminada es demasiado pequeña. 8 bytes es mínimo y se recomiendan 16.
CodesInChaos

Respuestas:

111

El prefijo o sufijo es irrelevante, solo se trata de agregar algo de entropía y longitud a la contraseña.

Debes considerar esas tres cosas:

  1. La sal tiene que ser diferente para cada contraseña que almacene. (Este es un malentendido bastante común).
  2. Use un generador de números aleatorios criptográficamente seguro.
  3. Elige una sal lo suficientemente larga. Piensa en el problema del cumpleaños.

Hay una excelente respuesta de Dave Sherohman a otra pregunta de por qué debería usar sales generadas aleatoriamente en lugar del nombre de un usuario (u otros datos personales). Si sigue esas sugerencias, realmente no importa dónde ponga su sal.

Georg Schölly
fuente
44
Agregué un enlace a una pregunta anterior, lea esas respuestas. Básicamente, al no usar una sal aleatoria diferente por contraseña, está asumiendo un riesgo de seguridad innecesario, que podría ser un problema real en el futuro.
Georg Schölly
39
La sal aleatoria en todo el sitio es mala, ya que un atacante puede calcular previamente tablas de arcoíris y tomar toda su base de datos de usuarios. Si no comprende esto, no escriba sistemas de inicio de sesión / seguridad :) - NECESITA sales por usuario.
snemarch
3
Sí, sal por usuario. Idealmente, con las iteraciones por usuario almacenadas (para que pueda aumentar la cantidad de iteraciones utilizadas con el tiempo). Cualquier marco decente tendrá esto incorporado. (.NET tiene PasswordDeriveBytes que se encargará de todo por usted.)
MichaelGG
2
Si está diseñando algún tipo de sistema de seguridad, es una locura no usar sal por usuario. su sitio podría no ser súper interesante, pero tenga en cuenta a los usuarios utilizar la misma contraseña en varios sitios ... tratando de mantener la base de datos segura tiende a fallar :)
snemarch
2
Por supuesto, las sales protegen contra los ataques de diccionario, precisamente al hacerlos mucho más lentos. El uso de sales en las contraseñas es mucho anterior a las tablas del arco iris. Se agregaron sales específicamente para ralentizar los ataques del diccionario, al evitar que los atacantes usen una contraseña una vez y luego la comparen con todos los usuarios.
Glenn Maynard
27

Creo que todo es semántica. Ponerlo antes o después no importa, excepto contra un modelo de amenaza muy específico.

El hecho de que esté allí se supone que vence a las mesas arcoiris.

El modelo de amenaza al que aludí sería el escenario en el que el adversario puede tener tablas del arco iris de sales comunes agregadas / antepuestas a la contraseña. (Diga la NSA) Está adivinando que lo tienen adjunto o antepuesto, pero no ambos. Eso es tonto, y es una suposición pobre.

Sería mejor asumir que tienen la capacidad de almacenar estas tablas de arcoíris, pero no, digamos, tablas con sales extrañas intercaladas en el medio de la contraseña. En ese caso estrecho, conjeturaría que intercalar sería lo mejor.

Como dije. Es semántica. Elija una sal diferente por contraseña, una sal larga e incluya caracteres extraños como símbolos y códigos ASCII: © ¤¡

Tom Ritter
fuente
@onebyone, maldita sea! ¡Ha descubierto mi sal de 'passwordsalt'!
Samuel
66
@Samuel: No sé ustedes, pero usamos '12345' para nuestra sal. :)
Randolpho el
@onebyone válido. Realmente quise decir "común" como "todas las sales de longitud X en el conjunto de caracteres Y" donde X, Y son razonables; digamos 20 caracteres y alfanuméricos mayúsculas / minúsculas. Extensible decir todas las cadenas hexadecimales bajo longitud Z (digamos 160) ya que creo una tabla de arco iris de hash hash sería útil ..
Tom Ritter
1
@Randolpho: ¡Oye, esa también es mi sal! ¿Cuáles son las probabilidades?
Adrien
Y asegúrese de que la sal no sea predecible / Aleatoria: stackoverflow.com/questions/1645161/…
Jacco
18

La verdadera respuesta, que nadie parece haber tocado, es que ambos están equivocados . Si va a implementar su propio cripto, no importa cómo parte de un trivial que creen que está haciendo, que va a cometer errores.

HMAC es un mejor enfoque, pero incluso si está utilizando algo como SHA-1, ya ha elegido un algoritmo que no es adecuado para el hash de contraseña debido a su diseño de velocidad. Use algo como bcrypt o posiblemente scrypt y elimine el problema de sus manos por completo.

Ah, y ni siquiera piense en comparar los hashes resultantes para la igualdad con su lenguaje de programación o las utilidades de comparación de cadenas de base de datos. Aquellos comparan carácter por carácter y cortocircuito como falsesi un personaje difiere. Así que ahora los atacantes pueden usar métodos estadísticos para tratar de averiguar cuál es el hash, un personaje a la vez.

Stephen Touset
fuente
1
Con respecto al último párrafo: ¿cómo podría el atacante obtener información sobre el número exacto de caracteres que la comparación ha fallado? Esto no tiene sentido ..
halloweenlv
1
Ambos son correctos e incorrectos. Los ataques de tiempo son reales y se ha demostrado repetidamente que son viables con una precisión aterradora incluso a través de conexiones de red de latencia variable para determinar exactamente dónde falló la comparación. Dicho esto, los ataques de temporización no son realmente aplicables a los hashes de contraseñas comunes, ya que es computacionalmente inviable encontrar entradas que solo cambian pequeñas partes de la salida.
Stephen Touset el
9

No debería hacer ninguna diferencia. El hash no será más fácil de adivinar donde sea que ponga la sal. Las colisiones de hash son raras e impredecibles, en virtud de ser intencionalmente no lineales. Si marcara una diferencia en la seguridad, eso sugeriría un problema con el hash, no con la salazón.

Phil H
fuente
1
Las colisiones de hash dependen del tamaño del hash. Gracias al problema del cumpleaños, las colisiones son bastante probables.
Georg Schölly
2
Solo si trunca el resultado. De todos modos, todavía mantengo el punto de que no hará ninguna diferencia dónde está la sal, porque el objetivo del hash es hacer que la relación entre entrada y salida no contenga patrones.
Phil H
7

Si utiliza un hash criptográficamente seguro, no debería importar si realiza un prefijo previo o posterior; Un punto de hash es que un solo cambio de bit en los datos de origen (sin importar dónde) debería producir un hash diferente.

Lo que es importante, sin embargo, es el uso de sales de largo, generando con un PRNG criptográfica adecuada, y teniendo sales por usuario. El almacenamiento de las sales por usuario en su base de datos es no un problema de seguridad, utilizando un hash de todo el sitio es .

snemarch
fuente
2
Respuesta incorrecta: un atacante podría calcular previamente MD (pass) para muchas contraseñas de uso frecuente y luego calcular MD (pass + salt) de forma muy económica porque el resumen de mensajes funciona de manera incremental para admitir la transmisión.
Erwan Legrand
5

En primer lugar, el término "tabla arcoiris" se usa constantemente de forma indebida. Una tabla de "arco iris" es solo un tipo particular de tabla de búsqueda, una que permite un tipo particular de compresión de datos en las teclas. Al cambiar el cálculo por espacio, una tabla de búsqueda que tomaría 1000 TB se puede comprimir mil veces para que se pueda almacenar en una unidad de disco más pequeña.

Debería preocuparse por las tablas de búsqueda de hash a contraseña, arco iris o de otro tipo.

@ onebyone.livejournal.com:

El atacante tiene 'tablas de arcoíris' que consisten no en los hash de las palabras del diccionario, sino en el estado del cálculo de hash justo antes de finalizar el cálculo de hash.

Entonces, podría ser más barato forzar por fuerza bruta una entrada de archivo de contraseña con sal de prefijo que el prefijo de sal: para cada palabra del diccionario, a su vez, cargaría el estado, agregaría los bytes de sal al hash y luego lo finalizaría. Con la sal prefijada no habría nada en común entre los cálculos para cada palabra del diccionario.

Para una función hash simple que escanea linealmente a través de la cadena de entrada, como un generador congruencial lineal simple, este es un ataque práctico. Pero una función hash criptográficamente segura está diseñada deliberadamente para tener múltiples rondas, cada una de las cuales usa todos los bits de la cadena de entrada, por lo que calcular el estado interno justo antes de la adición de la sal no tiene sentido después de la primera ronda. Por ejemplo, SHA-1 tiene 80 rondas.

Además, los algoritmos de hash de contraseña como PBKDF componen su función hash varias veces (se recomienda iterar PBKDF-2 un mínimo de 1000 veces, cada iteración aplicando SHA-1 dos veces) haciendo que este ataque sea doblemente poco práctico.

cygil
fuente
Debe verificar la descripción de las rondas. Las rondas son por fragmento, no todo el mensaje. (De lo contrario, el hash de transmisión de datos requeriría rebobinar una y otra vez). Pero el uso de iteraciones evita el problema que alguien menciona.
MichaelGG
4

BCrypt hash si la plataforma tiene un proveedor. Me encanta cómo no te preocupas por crear las sales y puedes hacerlas aún más fuertes si quieres.

Samuel
fuente
3
Por lo que sé, BCrypt Hash necesita sal, como cualquier otro esquema de hash.
Jacco
2

Insertar la sal un número arbitrario de caracteres en la contraseña es el caso menos esperado y, por lo tanto, el más "seguro" socialmente, pero en realidad no es muy significativo en el caso general, siempre que esté utilizando una contraseña única y larga. cuerdas para sales.

jeffcook2150
fuente