Sal no aleatoria para hashes de contraseña

89

ACTUALIZACIÓN: Recientemente aprendí de esta pregunta que en toda la discusión a continuación, yo (y estoy seguro de que otros también lo hicieron) fue un poco confuso: lo que sigo llamando una tabla de arco iris, de hecho se llama una tabla hash. Las tablas de arco iris son criaturas más complejas y en realidad son una variante de Hellman Hash Chains. Aunque creo que la respuesta sigue siendo la misma (ya que no se reduce al criptoanálisis), parte de la discusión puede estar un poco sesgada.
La pregunta: " ¿Qué son las tablas arcoíris y cómo se usan? "


Por lo general, siempre recomiendo usar un valor aleatorio criptográficamente fuerte como salt, para usarlo con funciones hash (por ejemplo, para contraseñas), como para protegerse contra ataques de Rainbow Table.

Pero, ¿es realmente criptográficamente necesario que la sal sea aleatoria? ¿Sería suficiente algún valor único (único por usuario, por ejemplo, userId) a este respecto? De hecho, evitaría el uso de una sola Tabla Rainbow para descifrar todas (o la mayoría) de las contraseñas del sistema ...
Pero, ¿la falta de entropía realmente debilita la fuerza criptográfica de las funciones hash?


Tenga en cuenta que no estoy preguntando por qué usar sal, cómo protegerla (no es necesario), usar un solo hash constante (no hacerlo) o qué tipo de función hash usar.
Si la sal necesita entropía o no.


Gracias a todos por las respuestas hasta ahora, pero me gustaría centrarme en las áreas con las que estoy (un poco) menos familiarizado. Principalmente implicaciones para el criptoanálisis: lo agradecería más si alguien tuviera alguna información del punto de vista cripto-matemático.
Además, si hay vectores adicionales que no se han considerado, también es una gran entrada (ver el punto de @Dave Sherohman en múltiples sistemas).
Más allá de eso, si tiene alguna teoría, idea o mejor práctica, respalde esto con pruebas, escenarios de ataque o evidencia empírica. O incluso consideraciones válidas para compensaciones aceptables ... Estoy familiarizado con las Mejores Prácticas (B mayúscula P) sobre el tema, me gustaría demostrar qué valor proporciona realmente.


EDITAR: Algunas respuestas realmente buenas aquí, pero creo que, como dice @Dave, se reduce a Rainbow Tables para nombres de usuarios comunes ... y posibles nombres menos comunes también. Sin embargo, ¿qué pasa si mis nombres de usuario son únicos a nivel mundial? No es necesariamente único para mi sistema, sino para cada usuario, por ejemplo, dirección de correo electrónico.
No habría ningún incentivo para construir un RT para un solo usuario (como enfatizó @Dave, la sal no se mantiene en secreto), y esto aún evitaría la agrupación en clústeres. El único problema sería que podría tener el mismo correo electrónico y contraseña en un sitio diferente, pero la sal no lo evitaría de todos modos.
Entonces, todo se reduce al criptoanálisis: ¿ES la entropía necesaria o no? (Mi pensamiento actual es que no es necesario desde el punto de vista del criptoanálisis, sino por otras razones prácticas).

Ávido
fuente
Debo decir que estoy confundido por muchas de las respuestas a continuación. El objetivo principal del uso de sal es simplemente evitar el ataque de la tabla de arco iris, por lo que cualquier cosa única para el usuario debe hacer, ya que obliga al atacante a recrear una tabla de arco iris para cada sal. mi 2c.
Goran
Si se necesita sal para, por ejemplo. sitio, a menudo tiene identificadores en las URL. Si el atacante sabe (y suponemos que lo sabe) que la contraseña salt es userid + username, es bastante fácil modificar el ataque para evitar el valor de la sal.
dmajkic
@dmajkic, salt está destinado a prevenir ataques RT y diferenciar las mismas contraseñas para diferentes usuarios. Esto es un hecho, incluso con nombres de usuario.
AviD
@AviD: Eso es cierto. Pero si conozco mi hash para mi pase, y sé que salt es mi nombre de usuario, entonces puedo crear fácilmente un valor de pase hash para cualquier palabra del diccionario y compararlo con el hash de pase de otra persona. Por eso el tiempo es mejor que el nombre de usuario.
dmajkic
1
Acabo de encontrar un artículo en el sitio web del Consorcio de Seguridad de PHP que en su ejemplo usa un número aleatorio con hash md5 como sal phpsec.org/articles/2005/password-hashing.html
helloworlder

Respuestas:

156

La sal se almacena tradicionalmente como un prefijo de la contraseña hash. Esto ya lo da a conocer a cualquier atacante con acceso al hash de la contraseña. Usar el nombre de usuario como salt o no no afecta ese conocimiento y, por lo tanto, no tendría ningún efecto en la seguridad de un solo sistema.

Sin embargo, usar el nombre de usuario o cualquier otro valor controlado por el usuario como sal reduciría la seguridad entre sistemas, ya que un usuario que tuviera el mismo nombre de usuario y contraseña en varios sistemas que usaran el mismo algoritmo de hash de contraseña terminaría con el mismo hash de contraseña en cada uno de esos sistemas. No considero que esto sea una responsabilidad importante porque yo, como atacante, primero probaría contraseñas que se sabe que una cuenta objetivo ha usado en otros sistemas antes de intentar cualquier otro medio de comprometer la cuenta. Los hash idénticos solo me dirían de antemano que la contraseña conocida funcionaría, no facilitarían el ataque real. (Tenga en cuenta, sin embargo, que una comparación rápida de las bases de datos de la cuenta proporcionaría una lista de objetivos de mayor prioridad, ya que me diría quién está reutilizando contraseñas y quién no).

El mayor peligro de esta idea es que los nombres de usuario se reutilizan comúnmente; casi cualquier sitio que desee visitar tendrá una cuenta de usuario llamada "Dave", por ejemplo, y "admin" o "root" son aún más comunes, lo que haría la construcción de tablas de arco iris dirigidas a usuarios con esos nombres comunes es mucho más fácil y eficaz.

Ambos defectos podrían abordarse de manera efectiva agregando un segundo valor de sal (ya sea fijo y oculto o expuesto como sal estándar) a la contraseña antes de aplicar el hash, pero, en ese punto, es posible que simplemente esté usando sal entrópica estándar de todos modos. de trabajar el nombre de usuario en él.

Editado para agregar: mucha gente está hablando de entropía y si la entropía en la sal es importante. Lo es, pero no por la razón que la mayoría de los comentarios parecen pensar.

La idea general parece ser que la entropía es importante, por lo que la sal será difícil de adivinar para un atacante. Esto es incorrecto y, de hecho, completamente irrelevante. Como varias personas han señalado algunas veces, los ataques que se verán afectados por salt solo pueden ser realizados por alguien con la base de datos de contraseñas y alguien con la base de datos de contraseñas puede simplemente mirar para ver cuál es el salt de cada cuenta. Si se puede adivinar o no, no importa cuándo puede buscarlo trivialmente.

La razón por la que la entropía es importante es evitar la agrupación de valores de sal. Si la sal se basa en el nombre de usuario y sabe que la mayoría de los sistemas tendrán una cuenta llamada "root" o "admin", entonces puede hacer una tabla de arco iris para esas dos sales y romperá la mayoría de los sistemas. Si, por otro lado, se usa una sal aleatoria de 16 bits y los valores aleatorios tienen una distribución aproximadamente uniforme, entonces necesita una tabla de arco iris para las 2 ^ 16 sales posibles.

No se trata de evitar que el atacante sepa cuál es la sal de una cuenta individual, se trata de no darles el objetivo grande y gordo de una sola sal que se utilizará en una proporción sustancial de objetivos potenciales.

Dave Sherohman
fuente
Convenido. Pondría más énfasis en la reutilización de nombres de usuario, ya que creo que ese es el ataque con más probabilidades de tener éxito contra sistemas hipotéticos que usan el nombre de usuario como sal, que habría fallado contra un sistema que usa sal aleatoria.
Steve Jessop
Aprecio su punto sobre la seguridad entre sistemas. Además, supongo que en el futuro no es improbable que veamos tablas de arco iris específicas del usuario ...
AviD
@AviD: ¿Eso crees? Ese es un vector de ataque bastante específico.
David Grant
2
No para generar sales, no. Los únicos ataques que se ven afectados por la sal son los que se realizan directamente contra las contraseñas hash. Un ataque no puede realizar este tipo de ataque a menos que tengan una copia de su base de datos de contraseñas, que también contendrá las sales. Dado que el atacante ya tendrá las sales en su poder, solo requieren la entropía suficiente para evitar tener múltiples contraseñas hash con la misma sal, que proporcionará cualquier (P) RNG básico.
Dave Sherohman
3
@ acidzombie24: Usar una única sal fija (generalmente llamada "nonce" en mi experiencia) para todas las contraseñas es menos seguro que usar una única sal aleatoria para cada contraseña, ya que aún permite a un atacante determinar trivialmente si dos o más cuentas comparten la misma contraseña. Por otro lado, es probable que el nonce se almacene en su código en lugar de en la base de datos, por lo que un atacante que solo tenga su base de datos no tendrá acceso a ella; debido a esto, la opción más segura es usar tanto un nonce de todo el sistema (almacenado en el código) como un salt por contraseña (almacenado en la base de datos).
Dave Sherohman
29

El uso de una sal de alta entropía es absolutamente necesario para almacenar las contraseñas de forma segura.

Tome mi nombre de usuario 'gs' y agréguelo a mi contraseña 'MyPassword' le da gsMyPassword. Esto se puede romper fácilmente usando una tabla de arco iris porque si el nombre de usuario no tiene suficiente entropía, podría ser que este valor ya esté almacenado en la tabla de arco iris, especialmente si el nombre de usuario es corto.

Otro problema son los ataques en los que se sabe que un usuario participa en dos o más servicios. Hay muchos nombres de usuario comunes, probablemente los más importantes son admin y root. Si alguien creara una tabla de arcoíris que tuviera sales con los nombres de usuario más comunes, podría usarlas para comprometer cuentas.

Solían tener una sal de 12 bits . 12 bits son 4096 combinaciones diferentes. Eso no era lo suficientemente seguro porque esa gran cantidad de información se puede almacenar fácilmente hoy en día . Lo mismo se aplica a los 4096 nombres de usuario más utilizados. Es probable que algunos de sus usuarios elijan un nombre de usuario que pertenezca a los nombres de usuario más comunes.

Encontré este verificador de contraseñas que calcula la entropía de su contraseña. Tener una entropía más pequeña en las contraseñas (como usar nombres de usuario) hace que sea mucho más fácil para las tablas de arco iris, ya que intentan cubrir al menos todas las contraseñas con entropía baja, porque es más probable que ocurran.

Georg Schölly
fuente
1 para un punto bueno, sin embargo, que se trata de un potencial enorme tabla de arco iris. Para cubrir todos los valores de la longitud de gsMyPassword (asumiendo alfanuméricos de mayúsculas y minúsculas) se requieren 36 ^ 12 filas en la tabla.
David Grant
A continuación: el proyecto de tabla de arco iris distribuida tiene 63,970 hashes agrietados, ¡pero 36 ^ 12 es 4,738,381,338,321,616,896!
David Grant
Gracias, y esto tiene sentido, pero como señaló el señor PotatoHead, todavía está ampliando su espacio más allá de la posibilidad razonable de romper con RT. Además, suponiendo que mis nombres de usuario tengan al menos 6-8 caracteres, ¿qué valor adicional necesario proporciona la entropía?
AviD
@Potato: asume una tabla de arco iris que contiene todas las combinaciones posibles de caracteres alfanuméricos. Este no tiene por qué ser el caso, una tabla arcoíris efectiva contendrá hashes para contraseñas / hashes comunes. La sal está ahí para proteger contra ataques de diccionario o combinación de tabla de arco iris / diccionario.
Guillaume
3
Usar el nombre de usuario como sal también es una mala idea para los sistemas en los que hay una cuenta de alto privilegio con un nombre predecible: "Administrador" en Windows, "root" en * nix, "sa" en MSSQL, etc.
nadie
8

Es cierto que el nombre de usuario por sí solo puede ser problemático, ya que las personas pueden compartir nombres de usuario entre diferentes sitios web. Pero no debería ser problemático si los usuarios tuvieran un nombre diferente en cada sitio web. Entonces, ¿por qué no hacerlo único en cada sitio web? Hash la contraseña algo así

hashfunction ("www.yourpage.com /" + nombre de usuario + "/" + contraseña)

Esto deberia resolver el problema. No soy un maestro del criptoanálisis, pero dudo que el hecho de que no usemos alta entropía debilitaría el hash.

konne
fuente
Creo que tienes razón en que esto es suficiente. Sin embargo, dado que los hashes son un campo matemático complicado y es muy posible que las sales de baja entropía hagan que los hashes sean más fáciles de adivinar en el futuro (especialmente cuando los hashes se rompen), no apostaría por la seguridad, cuando lo comprobado Una solución más segura no es mucho más cara.
Georg Schölly
7

Me gusta usar ambos: una sal por registro aleatoria de alta entropía, más la identificación única del registro en sí.

Aunque esto no agrega mucho a la seguridad contra ataques de diccionario, etc., elimina el caso marginal en el que alguien copia su sal y hash en otro registro con la intención de reemplazar la contraseña con la suya propia.

(Es cierto que es difícil pensar en una circunstancia en la que esto se aplique, pero no veo ningún daño en los cinturones y aparatos ortopédicos cuando se trata de seguridad).

teedyay
fuente
Me gusta la idea de vincular la contraseña al usuario. Pero si el atacante puede cambiar la contraseña, seguramente también podrá cambiar la identificación.
Georg Schölly
Depende de cuál sea el ID: uso la clave principal de la tabla, que realmente no se puede cambiar a voluntad. TBH, si el hacker está escribiendo en su base de datos, ya está en un problema bastante grande ...
teedyay
3
No, me gusta. Un atacante es a menudo un "interno". Podría imaginar escenarios en los que lo que busca no está en la base de datos, pero si puede sobrescribir las credenciales en la base de datos, puede autenticarse para hacer lo que quiera.
erickson
1
Buen punto. Descubrimos que es cada vez más difícil agregar el primer usuario a una nueva base de datos: hemos hecho nuestras aplicaciones tan seguras que apenas podemos piratearlas nosotros mismos. [Además, use un salt específico de la aplicación para que no pueda copiar las credenciales de una base de datos a otra.]
teedyay
Finalmente encontré a alguien diciendo esto: agregando algo específico del usuario a la sal. Eso evita que un intruso copie algunas credenciales a otro usuario y también evita que un pirata informático adivine cualquier contraseña si logra alcanzar su campo de hash y sal en la tabla. Una cosa más que me gusta hacer: no usar un número redondo de iteraciones en el hash. No vayas por 10k o 20k, sino algo como 19835.
Andrew
3

Si la sal es conocida o fácil de adivinar, no ha aumentado la dificultad de un ataque de diccionario. Incluso puede ser posible crear una tabla de arco iris modificada que tenga en cuenta una sal "constante".

El uso de sales únicas aumenta la dificultad de los ataques de diccionario BULK.

Sería ideal tener un valor de sal único y criptográficamente fuerte.

HUAGHAGUAH
fuente
2
El objetivo de la tabla del arco iris es que los valores están pregenerados y que si está generando la tabla para un valor (por ejemplo, una contraseña) MÁS una constante dada, esa es una tabla completamente diferente, y también podría simplemente pruebe el resultado hash directamente. :)
David Grant
1
Un hash constante no vale nada. Todas las contraseñas se pueden descifrar usando una sola tabla de arco iris. El propósito de la sal es que es imposible crear una tabla de arcoíris.
Georg Schölly
1
@gs - No veo por qué no puedes construir una tabla de arcoíris que "incluya" los efectos de una sal constante. El espacio de ataque (la contraseña) no habrá cambiado, por lo que la tabla no necesitará crecer, solo se recalculará.
HUAGHAGUAH
@Potato: depende de la compensación. Si los 20.000 inicios de sesión de su empresa se han codificado con la misma sal constante, puede ser más barato calcular una tabla de arco iris nueva que atacarlos con un diccionario individualmente. De ahí mi énfasis en "BULK".
HUAGHAGUAH
3

Diría que siempre que la sal sea diferente para cada contraseña, probablemente estará bien. El punto de la sal es que no puede usar la tabla de arco iris estándar para resolver todas las contraseñas en la base de datos. Entonces, si aplica una sal diferente a cada contraseña (incluso si no es aleatoria), el atacante básicamente tendría que calcular una nueva tabla de arco iris para cada contraseña, ya que cada contraseña usa una sal diferente.

Usar una sal con más entropía no ayuda mucho, porque en este caso se supone que el atacante ya tiene la base de datos. Dado que necesita poder recrear el hachís, ya debe saber qué es la sal. Por lo tanto, debe almacenar la sal o los valores que componen la sal en su archivo de todos modos. En sistemas como Linux, el método para obtener la sal es conocido, por lo que no sirve de nada tener una sal secreta. Debe asumir que el atacante que tiene sus valores hash probablemente también conozca sus valores de sal.

Kibbee
fuente
3
"El punto de la sal es que no se puede usar una tabla de arco iris estándar para resolver todas las contraseñas de la base de datos". Estoy en desacuerdo. El punto es que no puede usar una tabla de arco iris estándar para resolver ninguna contraseña. Si la sal es el nombre de usuario, entonces la tabla de arcoíris para "root" podría descifrar el pw de root.
Steve Jessop
Esa es probablemente la única regla que realmente importa. Básicamente, desea que la contraseña sea algo único en su sistema, pero no importa cuál sea. Sin embargo, todavía podría ser algo simple. No necesitas mucha entropía.
Kibbee
Este era mi pensamiento también, pero me quedé atascado en el "probablemente bien". Todavía no veo que se pruebe esta teoría, o al menos se verifique que no hay implicaciones de criptoanálisis.
AviD
@onebyone: Si la sal consiste en nombre de usuario + valor local constante (a menudo uso ':'), entonces eso aún arruina los RT estandarizados, a menos que haya una variedad de ellos que incluyan nombres de usuario comunes y valores de sal estáticos comunes. Más bien sospecho que ese no es el caso.
nsayer
Junto con nsayer. Podría usar una cadena constante en todo el sistema, para la que no habría un RT pregenerado, como # (D83d8, junto con el nombre de usuario como la sal, y eso probablemente evitaría cualquier ataque de tabla de arco iris.
Kibbee
3

¡La fuerza de una función hash no está determinada por su entrada!

El uso de una sal que sea conocida por el atacante obviamente hace que la construcción de una tabla de arcoíris (particularmente para nombres de usuario codificados como root ) sea más atractiva, pero no debilita el hash . El uso de una sal desconocida para el atacante hará que el sistema sea más difícil de atacar.

La concatenación de un nombre de usuario y una contraseña aún podría proporcionar una entrada para una tabla de arco iris inteligente, por lo que usar una sal de una serie de caracteres pseudoaleatorios, almacenados con la contraseña hash es probablemente una mejor idea. Como ilustración, si tuviera el nombre de usuario "papa" y la contraseña "cerveza", la entrada concatenada para su hash es "papa cerveza", que es una entrada razonable para una tabla de arco iris.

Cambiar la sal cada vez que el usuario cambia su contraseña podría ayudar a derrotar ataques prolongados, al igual que la aplicación de una política de contraseña razonable, por ejemplo, mayúsculas y minúsculas, puntuación, longitud mínima, cambio después de n semanas.

Sin embargo, diría que su elección de algoritmo de resumen es más importante. El uso de SHA-512 resultará más complicado para alguien que genere una tabla de arcoíris que MD5, por ejemplo.

David Grant
fuente
La fuerza de la función no cambia, pero la salida definitivamente cambia. Si la entrada puede ser influenciada o conocida, entonces quizás se pueda deducir algo sobre el valor hash. Ese es el riesgo.
Martin Carpenter
@Martin: ¡Lo único que debería poder deducir del valor hash si tiene o no una coincidencia! Poner "roota" o "rootb" (donde "a" y "b" representan la contraseña) en una función hash le dará una salida radicalmente diferente.
David Grant
Las sales son conocidas por un atacante que usa tablas de arco iris.
Georg Schölly
El servidor debe conocer la sal sin cifrar (para comparar la contraseña con el hash), por lo que se puede dar por sentado que un atacante tiene acceso a la sal o que puede obtenerla muy fácilmente.
Georg Schölly
Correcto, correcto, eso es un hecho; para ser más específico, me refiero a la fuerza del criptosistema general (o subsistema, wrt hashes).
AviD
1

Salt debe tener tanta entropía como sea posible para garantizar que, si un valor de entrada dado se utiliza con hash varias veces, el valor de hash resultante será, lo más cercano posible, siempre diferente.

El uso de valores de sal en constante cambio con la mayor entropía posible en la sal garantizará que la probabilidad de hash (por ejemplo, contraseña + sal) produzca valores de hash completamente diferentes.

Cuanto menos entropía haya en la sal, más posibilidades tendrá de generar el mismo valor de sal, por lo que tendrá más posibilidades de generar el mismo valor hash.

Es la naturaleza de que el valor hash sea "constante" cuando la entrada es conocida y "constante" lo que permite que los ataques de diccionario o las tablas de arco iris sean tan efectivos. Al variar el valor de hash resultante tanto como sea posible (mediante el uso de valores de sal de alta entropía), se asegura que el hash de la misma entrada + sal aleatoria producirá muchos resultados de valor de hash diferentes, derrotando (o al menos reduciendo en gran medida la efectividad de) la tabla de arco iris Ataques

CraigTP
fuente
Nuevamente, no me refiero al uso de una única sal constante, sino a un valor no aleatorio, pero único para el usuario. Por ejemplo, userId.
AviD
El punto es que su valor de sal nunca debe ser constante. Cada cosa que hagas hash, ya sea el mismo valor de "entrada" o no, debe tener una sal diferente. Dave Sherohman explica las desventajas de usar incluso valores únicos para el usuario que esencialmente permanecen iguales con cada cálculo hash.
CraigTP
-1

La entropía es el punto de valor de la sal.

Si hay alguna "matemática" simple y reproducible detrás de la sal, entonces es lo mismo que la sal no está ahí. Solo agregar valor de tiempo debería estar bien.

dmajkic
fuente
No entiendo este comentario. Dices "usa la entropía" y luego: "usa el tiempo".
Martin Carpenter
si el nombre de usuario se usa para la sal, no es lo suficientemente entrópico. Pero si usa nombre de usuario + fecha y hora actual, lo es, ya que es difícil adivinar cuándo se creó exactamente la sal.
dmajkic
"suficientemente entrópico" es subjetivo; es tu estándar. Basar este valor en el tiempo puede no ser adecuado.
Martin Carpenter
No existe tal cosa como "absoluta aleatoriedad verdadera". Depende de nosotros decir cuándo es "suficientemente bueno". Si cree que en este caso el tiempo no es suficiente, utilice otra cosa. stackoverflow.com/questions/84556/…
dmajkic
En realidad, el punto de la sal es hacer que cada resultado de hash sea único, para evitar (a) ataques de tablas de arco iris y (b) identificación de contraseña idéntica. La pregunta es, ¿para qué más se necesita la entropía, si es que se necesita?
AviD