What's the difference between bcrypt and hashi

2019-03-24 19:20发布

问题:

How is bcrypt stronger than, say,

def md5lots(password, salt, rounds):
    if (rounds < 1)
        return password
    else
        newpass = md5(password + salt)
        return md5lots(newpass, salt, rounds-1)

I get the feeling, given its hype, that more intelligent people than me have figured out that bcrypt is better than this. Could someone explain the difference in 'smart layman' terms?

回答1:

There are three significant differences between bcrypt and hashing multiple times with MD5:

  1. The size of the output: 128-bit (16-bytes) for MD5 and 448 bits (56-bytes) for bcrypt. If you store millions of hashes in a database, this has to be taken into account.
  2. Collisions and preimage attacks are possible against MD5.
  3. Bcrypt can be configured to iterate more and more as cpu's become more and more powerful.

Hence, using salting-and-stretching with MD5 is not as safe as using bcrypt. This issue can be solved by selecting a better hash function than MD5.

For example, if SHA-256 is selected, the output size will be 256-bits (32-bytes). If the salting-and-stretching can be configured to increase the number of iterations like bcrypt, then there is no difference between both methods, except the amount of space required to store result hashes.



回答2:

The principal difference - MD5 and other hash functions designed to verify data have been designed to be fast, and bcrypt() has been designed to be slow.

When you are verifying data, you want the speed, because you want to verify the data as fast as possible.

When you are trying to protect credentials, the speed works against you. An attacker with a copy of a password hash will be able to execute many more brute force attacks because MD5 and SHA1, etc, are cheap to execute.

bcrypt in contrast is deliberately expensive. This matters little when there are one or two tries to authenticate by the genuine user, but is much more costly to brute-force.



回答3:

You are effectively talking about implementing PBKDF2 or Password-Based Key Derivation Function. Effectively it is the same thing as BCrypt, the advantage being that you can lengthen the amount of CPU time it takes to derive a password. The advantage of this over something like BCrypt is that, by knowing how many 'Iterations' you have put the password through, when you need to increase it you could do it without resetting all the passwords in the database. Just have your algorithm pick up the end result as if it were at the nth iteration (where n is the previous itteration count) and keep going!

It is recomended you use a proper PBKDF2 library instead of creating your own, because lets face it, as with all cryptography, the only way you know if something is safe is if it has been 'tested' by the interwebs. (see here)

Systems that use this method:
.NET has a library already implemented. See it here
Mac, linux and windows file encryption uses many itteration (10,000+) versions of this encryption method to secure their file systems.
Wi-Fi networks are often secured using this method of encryption
Source

Thanks for asking the question, it forced me to research the method i was using for securing my passwords.

TTD



回答4:

Although this question is already answered, i would like to point out a subtle difference between BCrypt and your hashing-loop. I will ignore the deprecated MD5 algorithm and the exponential cost factor, because you could easily improve this in your question.

You are calculating a hash-value and then you use the result to calculate the next hash-value. If you look at the implementation of BCrypt, you can see, that each iteration uses the resulting hash-value, as well as the original password (key).

Eksblowfish(cost, salt, key)
  state = InitState()
  state = ExpandKey(state, salt, key)
  repeat (2^cost)
    state = ExpandKey(state, 0, key)
    state = ExpandKey(state, 0, salt)
  return state

This is the reason, you cannot take a Bcrypt-hashed password and continue with iterating, because you would have to know the original password then. I cannot prove it, but i suppose this makes Bcrypt safer than a simple hashing-loop.



回答5:

Strictly speaking, bcrypt actually encrypts the text:

OrpheanBeholderScryDoubt

64 times.

But it does it with a key that was derived from your password and some randomly generated salt.