security hash passwords md5 password-storage

security - ¿Por qué no usar MD5 para el hash de contraseña?



passwords password-storage (3)

El problema con MD5 es exactamente que es tan rápido que puede calcular aproximadamente 9 Giga MD5 / s con hardware común. Para aplicar fuerza bruta a un diccionario de inglés completo con aproximadamente 200000 palabras, solo necesita una fracción de milisegundo.

Esta es la razón por la cual los algoritmos hash apropiados como BCrypt ofrecen un factor de costo. El factor de costo define cuánto tiempo se necesita para calcular el hash y se puede aumentar en el futuro. 50 milisegundos para un inicio de sesión no es un obstáculo, pero para la fuerza bruta es mortal.

Tengo un amigo que es un hacker de sombrero blanco. Él dice que md5 no es realmente tan malo y en realidad es realmente seguro, solo si lo usamos correctamente.

Creo que tiene razón. Como sé, hay 3 formas de romper hashes:

  1. Usar tablas Rainbow (que se pueden asegurar con una sal larga / aleatoria)
  2. Colisión (que puede evitarse mediante múltiples sales o hashes, como en el ejemplo a continuación)
  3. Tiempo de generación (que no es muy importante si utilizamos un valor de sal lo suficientemente largo por cada usuario - AFAIK)

Mi amigo y yo creemos que Blowfish no es realmente necesitado, también puede ser dañino porque puede ralentizar el proceso de validación de contraseña y puede usarse con ataques DDOS para descomponer el servidor incluso con menos recursos de ataque.

Entonces, ¿quiero asegurarme de que el siguiente algoritmo sea realmente seguro o no? Y, ¿hay alguna razón real para utilizar el algoritmo de hash Blowfish o no?

// return a 256 bit salt + 128 bit md5 binary hash value function hash(password, salt=null) { salt = (salt != null) ? salt : Random256BitBinaryValueGenerator(); // What about using another user-specified parameter, like email address as salt? return salt + md5(salt + password) + md5(password + salt); // Or just use a non-cryptographic hash algorithm like crc32 to prevent collisions: // return salt + md5(salt + password) + crc32(salt + password); // Or even use two different salts: // return salt + md5(salt + password) + md5(''C'' + salt + password); } // check password function check(password, hash_value) { return hash(password, substring(hash_value, 0, 32)) == hash_value; }


La propiedad de resistencia a la colisión de MD5 se ha roto durante mucho tiempo. Tenga en cuenta que la resistencia de preimagen y la segunda resistencia de preimagen aún no se han agrietado, sin embargo, dado que existen mejores algoritmos (SHA-2), sería aconsejable pasar a estos en lugar de confiar en un hash criptográfico que ya ha comenzado a perder su valor. propiedades criptográficas Nota: La propiedad de resistencia a colisión no importa cuando se almacenan contraseñas hash; lo que debe asegurarse es que la propiedad de resistencia a la imagen previa sea sólida, que no sea computacionalmente factible encontrar la contraseña original dado un cierto valor hash (y sal). Como mencioné, dado que una de las propiedades criptográficas ya está rota, me preocuparía que las demás las sigan pronto.

Cuando almacena un hash de contraseña, debe crear cierta protección para que la contraseña original no se pueda recuperar en caso de que un atacante logre extraer estos hash. Esto es importante porque si un atacante logra recuperar la tabla de contraseña solo puede usar los datos para iniciar sesión directamente en su sistema o para iniciar sesión en otros sistemas donde el usuario ha reutilizado la misma contraseña.

Al almacenar contraseñas, es importante utilizar un algoritmo lento , como bcrypt, scrypt o pbkdf2. Un usuario legítimo solo debería experimentar el retraso una vez, al primer inicio de sesión. Un atacante tendrá que experimentar el retraso por cada contraseña que adivine; recuerde que las tablas de arco iris no se usarán aquí porque las contraseñas están saladas. El atacante analizará cada conjetura de contraseña de acuerdo con el algoritmo elegido y el recuento de iteraciones.

Es importante ajustar la cantidad de iteraciones para su sistema solo para que se use la "fuerza" correcta para no causar molestias reales a los usuarios legítimos al iniciar sesión en su sistema. Esto se conoce como número de "rondas" o "recuento de iteraciones". Por ejemplo, iterar durante aproximadamente un segundo debería ser suficiente. Puede ser seguro asumir que un atacante puede ejecutar hashes a diez veces la velocidad del hardware de su sistema. Por lo tanto, esto limita al atacante a 10 conjeturas por segundo, en lugar de dos mil millones con MD5.

En cuanto a los ataques DoS

Sí, el procesamiento adicional que realiza su aplicación hasta el inicio de sesión podría ser un objetivo para que un atacante envíe contraseñas realmente largas a su aplicación, o golpearlo repetidamente con solicitudes de inicio de sesión para consumir recursos de CPU y memoria en su servidor. Tienes razón en preocuparte .

Este tipo de ataques se pueden mitigar de las siguientes maneras:

  • Registre el nombre de usuario y la dirección IP de cada intento de inicio de sesión. Después de decir 6 intentos fallidos, introduzca un retraso en la respuesta de su aplicación si ese nombre de usuario o IP se repite nuevamente. Esto también ayudará a mitigar los ataques de adivinación de contraseña en general.
    • Por ejemplo, podría retrasar artificialmente 1 segundo, luego 2 segundos, luego 4 y hasta un valor razonable (por ejemplo, 16 segundos).
    • Esto tiene la ventaja de que un atacante no puede bloquear otra cuenta a propósito ya que el usuario legítimo solo tiene que esperar 16 segundos.
    • Un atacante podría usar una botnet y nombres de usuario aleatorios para omitir estas comprobaciones, sin embargo, necesitaría una gran cantidad de direcciones IP de las que necesitaría sin este control, y un atacante más informal tampoco sería consciente de que el retraso en la respuesta fue artificial.
  • Monitoree la cantidad de intentos de inicio de sesión en su sistema. Una vez que esté por encima de un umbral establecido (por ejemplo, 10 por segundo), introduzca un CAPTCHA para resolver y continuar el proceso de inicio de sesión. La tasa de umbral que elija depende en gran medida de la base de usuarios y la capacidad de su sistema.
  • Implemente la autenticación de dos factores. Solo proceda a validar la contraseña mediante hashing una vez que se haya validado la contraseña de un solo uso.

Usted habla de reducir la validación como un problema, pero es la única defensa contra un hash filtrado y un ataque de fuerza bruta. Las soluciones modernas calculan el valor repetidamente (es decir, miles de veces) solo para aumentar el costo del cálculo.