Sal no aleatoria para hashes de contraseñas
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) fui un poco confuso: lo que sigo llamando tabla arcoíris, de hecho se llama tabla hash. Las tablas Rainbow 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 podría estar un poco sesgada.
La pregunta: " ¿ Qué son las mesas arcoíris y cómo se utilizan? "
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 proteger contra ataques de Rainbow Table.
Pero, ¿es realmente criptográficamente necesario que la sal sea aleatoria? ¿Sería suficiente a este respecto algún valor único (único por usuario, por ejemplo, ID de usuario)? De hecho, impediría el uso de una sola Rainbow Table 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 salt, cómo protegerla (no es necesario), usar un único hash constante (no lo haga) o qué tipo de función hash usar.
Simplemente 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: agradecería mucho que alguien tuviera alguna aportación del punto de vista criptomatemático.
Además, si hay vectores adicionales que no se han considerado, también es un gran aporte (consulte el punto de @Dave Sherohman sobre múltiples sistemas).
Más allá de eso, si tiene alguna teoría, idea o mejor práctica, respaldela con pruebas, escenarios de ataque o evidencia empírica. O incluso consideraciones válidas para compensaciones aceptables... Estoy familiarizado con las mejores prácticas (mayúscula B mayúscula P) sobre el tema, me gustaría demostrar qué valor proporciona esto realmente.
EDITAR: Algunas respuestas realmente buenas aquí, pero creo que, como dice @Dave, todo 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 globalmente únicos? No necesariamente único para mi sistema, sino para cada usuario, por ejemplo, dirección de correo electrónico.
No habría ningún incentivo para crear 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. 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 necesaria la entropía o no? (Mi opinión actual es que no es necesario desde el punto de vista del criptoanálisis, pero sí lo es por otras razones prácticas).
Salt se almacena tradicionalmente como un prefijo de la contraseña hash. Esto ya lo hace saber 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 del sistema único.
Sin embargo, usar el nombre de usuario o cualquier otro valor controlado por el usuario como salt reduciría la seguridad entre sistemas, ya que un usuario que tuviera el mismo nombre de usuario y contraseña en múltiples sistemas que usan el mismo algoritmo de hash de contraseña terminaría con el mismo hash de contraseña. cada uno de esos sistemas. No considero que esto sea una responsabilidad importante porque yo, como atacante, probaría primero las contraseñas que se sabe que una cuenta objetivo ha utilizado en otros sistemas antes de intentar cualquier otro medio de comprometer la cuenta. Los hashes idénticos sólo me dirían de antemano que la contraseña conocida funcionará, no facilitarían el ataque real. (Sin embargo, tenga en cuenta que una comparación rápida de las bases de datos de las cuentas proporcionaría una lista de objetivos de mayor prioridad, ya que me diría quién reutiliza 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 incluso más comunes, lo que haría que La construcción de tablas de arco iris dirigidas a usuarios con esos nombres comunes es mucho más fácil y efectiva.
Ambas fallas 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 mejor que simplemente esté usando sal entrópica estándar de todos modos. de incluir el nombre de usuario en él.
Editado para agregar: Mucha gente habla sobre la entropía y si la entropía en la sal es importante. Lo es, pero no por la razón que parecen pensar la mayoría de los comentarios al respecto.
La idea general parece ser que la entropía es importante, por lo que a un atacante le resultará difícil adivinar la sal. Esto es incorrecto y, de hecho, completamente irrelevante. Como varias personas han señalado varias veces, los ataques que se verán afectados por la sal 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 la sal de cada cuenta. Si es adivinable o no, no importa cuándo puedas buscarlo trivialmente.
La razón por la que la entropía es importante es para evitar la agrupación de valores de sal. Si el salt 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 crear una tabla de arco iris para esas dos sales y descifrará la mayoría de los sistemas. Si, por otro lado, se utiliza una sal aleatoria de 16 bits y los valores aleatorios tienen una distribución aproximadamente uniforme, entonces necesitará una tabla de arcoíris para las 2^16 sales posibles.
No se trata de evitar que el atacante sepa cuál es la sal de una cuenta individual, sino de no darle el gran objetivo de una sola sal que se utilizará en una proporción sustancial de objetivos potenciales.
El uso de una sal de alta entropía es absolutamente necesario para almacenar contraseñas de forma segura.
Tome mi nombre de usuario 'gs' y agréguelo a mi contraseña 'MyPassword' que le da gsMyPassword. Esto se soluciona 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 sean 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 hoy en día tanta información se puede almacenar fácilmente . 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 el uso de nombres de usuario) hace que sea mucho más fácil para Rainbowtables, ya que intentan cubrir al menos todas las contraseñas con baja entropía, porque es más probable que ocurran.
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 suponer ningún problema que 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 como esto
función hash("www.tupágina.com/"+nombre de usuario+"/"+contraseña)
Esto deberia resolver el problema. No soy un maestro en criptoanálisis, pero dudo que el hecho de que no usemos alta entropía debilite el hash.