Sales de contraseña y aleatoriedad

14

Está bien, así que entiendo que los usuarios son el tipo de bestias a las que les gusta usar una contraseña y hacerla corta y fácil de recordar (como "doggies"). Si entiendo correctamente, esa es una de las razones por las que usamos las sales de contraseña. Añaden longitud y cierto nivel de aleatoriedad. Mi problema es cómo generarlos. La forma en que he estado generando mis sales (y los hashes de contraseña) en un proyecto reciente (todavía totalmente interno) es hacer lo siguiente:

  1. Agarra el tiempo en segundos desde la época
  2. Agarre el tiempo que se ha estado ejecutando el proceso (tan granular como lo permita el sistema operativo)
  3. Cree el hash MD5 de los dos resultados anteriores
  4. Agregue las 4 cadenas que ahora tengo en una combinación variable
  5. Almacena esto como texto simple
  6. Agregue la contraseña y el salt de varias maneras
  7. hash SHA-512 que para crear el hash de contraseña

¿Es esto suficientemente aleatorio? ¿Agrega suficiente entropía? Hace poco leí que necesito un algoritmo de hashing más fuerte (mirando bcrypt) y necesito múltiples hashes (1000+) para estar lo suficientemente seguro, pero ese no es el punto central de la pregunta.

    
pregunta Nakaan 12.12.2012 - 07:15
fuente

2 respuestas

17

Esto parece mal orientado.

El tiempo en segundos desde cualquier fuente carece de casi cualquier entropía y se puede adivinar casi de inmediato. Si su sistema operativo permite una granularidad de microsegundos para un proceso en ejecución, obtendrá 4 o 5 bits de entropía allí, desde los bits más bajos, pero mucho menos si alguien encuentra la manera de obtener el tiempo de actividad exacto del sistema.

Entonces estás hablando de MD5, que no es realmente útil en este caso. Todo lo que te da te da la impresión de que lo has hecho más aleatorio, sin hacerlo realmente aleatorio. En realidad, solo tiene un par de enteros que dependen de cada uno (el tiempo de proceso siempre estará sincronizado con el tiempo de actividad del sistema) y es completamente no aleatorio. Su sistema casi seguramente perderá su tiempo de actividad de una forma u otra. En realidad, sería mejor utilizar un LCG como rand() de PHP, ya que el estado interno no se puede adivinar como fácilmente.

Este enfoque para la generación de números aleatorios es malo, porque no es aleatorio en absoluto, y se puede predecir. Sin embargo, las sales no necesitan ser particularmente aleatorias, solo necesitan ser únicas; solo están ahí para prevenir ataques a la mesa del arco iris. La imprevisibilidad ayuda (consulte "cómo almacenar sal?" ) pero no está No se requiere completamente . En cualquier caso, hay algunos beneficios para hacer que la sal sea difícil de predecir.

Si estás en Linux, lee algunos bytes de /dev/urandom para generar el salt, no necesitas hacer nada más que tomar esos bytes y usarlos, porque ya son números aleatorios fuertes.

Si no, puede generar la sal como SHA256(username || email || time || mt_rand()) donde || denota concatenación, time es la hora actual del sistema en la resolución más alta que pueda obtener, y mt_rand() es un valor de salida de lo que sea El generador aleatorio está disponible en la biblioteca predeterminada de su lenguaje de programación. En PHP debería usar mt_rand en lugar de rand , ya que tiene mejores características. Esto proporciona suficiente entropía para que una sal sea muy difícil de adivinar de forma remota, especialmente dadas las oportunidades limitadas para la reutilización de combinaciones de nombre de usuario y correo electrónico.

Para almacenar la contraseña, definitivamente debería estar usando PBKDF2 o bcrypt. Un solo uso de una función hash criptográfica simplemente no es suficiente para protegerlo de los ataques de fuerza bruta, especialmente cuando casi todo el mundo tiene una GPU compatible con OpenCL en estos días.

    
respondido por el Polynomial 12.12.2012 - 08:03
fuente
2

En realidad, una sal no tiene que ser aleatoria; debe ser único . Esta es la singularidad mundial (única para todos los tiempos y para todos los servidores del mundo), y la forma más sencilla para lograr la singularidad es usar la aleatoriedad: genere 16 bytes (o más) con un generador aleatorio criptográficamente sólido , y la probabilidad de que alcances un valor de sal que ya se haya usado en otros lugares es lo suficientemente pequeña como para ser descuidada.

La aleatoriedad es difícil. Lo que presenta es la combinación de un generador de números aleatorios débiles y un mecanismo de codificación de contraseñas débiles. La forma adecuada para generar un salt es pedirle al generador de números pseudoaleatorios del sistema que lo haga por usted ( /dev/urandom en sistemas similares a Unix, CryptGenRandom() en Windows, System.Security.Cryptography.RNGCryptoServiceProvider en .NET. ..). Luego , usa el salt con un sistema de hashing de contraseña adecuado como bcrypt o PBKDF2 . La mayoría de las implementaciones de bcrypt harán la generación de sal por ti, así que eso es aún mejor.

    
respondido por el Thomas Pornin 28.12.2012 - 17:38
fuente

Lea otras preguntas en las etiquetas