Why not use MD5 for hashing passwords?

I have a friend who is a white hat hacker. He says that md5 is actually not that bad and is actually really safe, just if we use it correctly.

I believe he is right. As I know there are 3 ways to split hashes:

  • Using Rainbow Tables (which can be protected from long / random salt)
  • Collision (which can be prevented by multiple salts or hashes - as in the example below)
  • Generation time (which is not that important if we use a large enough salt value for each user - AFAIK)

My friend and I believe that Blowfish is not really needed and it can be harmful because it can slow down the password verification process and can be used with DDOS attacks to destroy a server with even fewer attak resources.

So, I want to make sure that the algorithm is really safe or not? And is there a real reason to go with the Blowfish hashing algorithm or not?

// 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;
}

      

+3


source to share


3 answers


collision property MD5 property has been violated for a long time. Note that Providence Resistance and Second Profile Resistance have not yet been cracked, however, since there are better algorithms out there (SHA-2), it would be wise to switch to them rather than relying on a cryptographic hash that has already begun to lose its cryptographic properties. Note. The collision resistance property is irrelevant when storing hashed passwords - which is what you need to make sure the preimage resistance property sounds - that it is impossible to compute to find the original password with a specific hash value (and salt). As I mentioned, since one of the cryptographic properties is already broken, I will be concerned that others will follow soon.

When you store the password hash, you have to create some protection that the original password cannot obtain if an attacker can extract those hashes. This is important because if an attacker only succeeds in obtaining the password table, they can then use the credentials to log into your system directly or to log on to other systems where the user has reused the same password.

When storing passwords, it is important to use a slow algorithm such as bcrypt, scrypt or pbkdf2. A valid user should only experience a delay once on first login. An attacker would have to experience a delay for every password they guess - remember that rainbow tables won't be used here because passwords are salted. The attacker will hash each password according to the algorithm you choose and the number of iterations.

It is important to tune the number of iterations for your system in order to properly use "force" to prevent legitimate users from getting really annoyed when logging into your system. This is known as the "rounds" or "iteration count". For example, a repetition of about one second should be sufficient. It's safe to assume that an attacker can go through hashes up to ten times faster than the speed of your system hardware. Therefore, this limits the attacker to 10 guesses per second, rather than two billion with MD5.



With regard to DoS attacks

Yes, the extra processing your app does before logging in could be a target for an attacker to send either very long passwords to your app, or hit it multiple times with login requests to consume CPU and memory resources on your server. You are right to worry .

These types of attacks can be mitigated in the following ways:

  • Register the username and IP address of each login attempt. After say 6 unsuccessful attempts, enter a delay in the response from your application if this username or IP is repeated again. It will also help mitigate password guessing attacks in general.
    • For example, you could artificially delay 1 second, then 2 seconds, then 4 and up to a reasonable value (for example, 16 seconds).
    • This has the advantage that an attacker cannot block another account, as the legitimate user only has to wait 16 seconds.
    • An attacker could use a botnet and random usernames to bypass these checks, however they would need a huge number of IP addresses than without this control, and a more casual attacker would also not know that the delay in response was artificial.
  • Monitor the number of login attempts. Once this exceeds the set threshold rate (for example, 10 per second), enter the CAPTCHA to decide to continue the login process. The threshold speed you choose depends on your user base and the capacity of your system.
  • Implementing two-factor authentication. Only validate the password with hashing once one password has been verified.
+11


source


The problem with MD5 is that it is so fast that you can calculate 9 Giga MD5 / s with shared hardware. It only takes you a million seconds to copy an entire English dictionary of about 200,000 words.



This is why suitable hashing algorithms like BCrypt offer a cost factor. The cost factor determines how long it takes to calculate the hash and can be increased in the future. 50 milliseconds for login is hardly an obstacle, but for brutal coercion it is deadly.

+4


source


You talk about slowing down the check as a problem, but that is the only defense against missing hash and brute force attacks. Modern solutions hash the value repeatedly (i.e. Thousands of times) just to increase the cost of the calculation.

0


source







All Articles