views:

7291

answers:

13

When you're hashing a password (or anything else) in PHP, does it make any difference if you use SHA or MD5?

A: 

The algorithm that is used to compute the hash is different. I prefer to use SHA when hashing. Also note that there are two groups of SHA hashes - SHA-1 and SHA-2.

Thomas Owens
Why do you prefer SHA over MD5?
vIceBerg
SHA-2, anyway, has less (known) collisions. I use SHA-512 for the critical stuff and 128 or 256 for everything else.
Thomas Owens
MD5 has known weaknesses. So does SHA-1, but they seem to be much harder to exploit.
Mihai Limbășan
+3  A: 

If you're comparing alternatives, you might also want to investigate the relatively new hash functions in PHP - it comes with a range of alternative hashes, if your server supports them.

The function hash_algos will return a list of all hash algorithms your server supports.

Phill Sacre
A: 

md5 generates a 32 chars hash, SHA1 a 40 chars hash... no matter what method you choose, i recommend to use a salt anyway

Jochen Hilgers
Not correct at all, not even if you substitute "byte" for "bit". MD5 generates a 128-bit (16-byte) hash. SHA-1 produces a 160-bit (20-byte) hash. Though they are often represented in hexadecimal, in which case the size required is twice the number of bytes.
Elias Yarrkov
i'm sorry... typed a litte bit to fast ;) i meant chars instead of bytes/bits
Jochen Hilgers
A: 

MD5 and SHA are both different algorithms, where MD5 is the weaker of the two. In fact, there's some relatively easy methods that allow people to reverse engineer a password that works for a specific MD5 hash using Rainbow tables, but that can be negated using the salt method that's mentioned in the same link. Ofcourse the same can be used with an SHA hash for even more security.

Linor
+19  A: 

Yeah, SHA and MD5 are different algorithms. SHA is considered more secure than MD5. And it doesn't matter if you are talking about the implementation of the algorithms that is distributed with PHP or any implementation. They produce the same result (md5 in php produces the same result as md5 in any other language).

Vasil
SHA1 is not considered more secure, SHA2XX is considered more secure http://ehash.iaik.tugraz.at/wiki/The_Hash_Function_Zoo
Sam Saffron
SHA1 is probably considering more secure than MD5. However SHA256 is more secure than SHA1
Rory
A: 

Yes, there's a difference. MD5 was broken and is no longer secure. Use sha1 with a big hash size (for example: sha-512). Also use a different salt for each hash. NEVER USE MD5 FOR PASSWORDS!!!. Also se the blog entry on md5 and rainbow tables from coding horror.

Kasprzol
MD5 was not "broken". Rather, it was found that MD5 hashes collide more often and that they contain less entropy than previously thought. It's hardly "broken".And not using MD5 won't save you from a Rainbow table attack. That's why you always salt your hashes.
Bob Somers
+3  A: 

There are attacks on parts of MD5 and SHA-1. NIST recommends that for new systems the developers should be using SHA256.

florin
256 is for the weak. 512 is where it's at. :P
Thomas Owens
Real men use /dev/random !
macbirdie
I thought real men used butterflies? (http://xkcd.com/378/)
Kris
+1  A: 

SHA is more secure than MD5, but I wouldn't recommend either for hashing passwords anymore. Here's a list of cryptographic hash functions. You should use the most secure one you can get an implementation of in PHP.

Bill the Lizard
@sambo99: Neither I, nor the question mention either salt or a birthday attack. Why wouldn't you chose the stronger hash when it's readily available?
Bill the Lizard
@Bill, there will always be a stronger hash function readily available, the thing is that without Salt ALL the hash functions have a serious flaw (rainbow tables) when it comes to hashing passwords. If the chance of me getting an MD5 collision is 1 / all the grains of sand in the world, its good enough for me. Using the stronger hashing function in this scenario will only protect you against birthday attacks. Meaning someone could create a malicious password Y that has the same hash as password X (provided they control the salt, which they don't)
Sam Saffron
+1  A: 
Kyle
A: 

While SHA-1 and MD5 are "broken", the "attack" isn't actually an attack. Except with MD5.

Security expert Schneier explains for us that all the vulnerability is the ability to generate two sets of data that collide. What does this mean to us? This means that you can figure out how to make two bits of data that will collide, but that's all you know. Because it would take an extremely long time to attack this way, it won't be used. Do not alternate methods because it increases collisions (the problem) and hash once with a dynamic salt for the greatest security.

MD5 is unwise to be used because it has been cracked, not just broken. This means data obscured by MD5 is unsafe and could be reproduced.

However, SHA-1 still is perfectly safe to use for password storage. You should never store your passwords like sha1('my password') in the database, however, and a static salt is only good so long as it isn't known (either by file-level access or by breaking into your settings table in the database).

In summary, the safest scheme for password storage (in general) is sha1($password . $username), which will return a 40 digit destructive hash of this. To brute-force this would require O(n*m) tries, where n is the number of words (in your dictionary) and m is the number of users.

Again, SHA-1 is "broken" but is not a risk yet; it will only be a risk when they can take the hash and regenerate the data on a whim.

The Wicked Flea
-1 there is no magical way of decompressing an MD5 hash into content. any mechanism for doing so will rely on having the hash and the content prior to the fact.
Sam Saffron
Never said there was a magical method to do this, did I? Your nitpick doesn't remove the truth that MD5 is insecure, given that a 1.6GHz system will compute a collision with UNRELATED (and significant) DATA within 8 hours ... and that only clock cycles are needed now.
The Wicked Flea
-1 for on my question for what? not understanding the concept. A dictionary attack is a pain compared to a rainbow table attack, but sure, if you have some way to store your salt outside of the DB, go for it. Read this: it got a +15 http://stackoverflow.com/questions/420843/need-some-help-understanding-password-salt/421081#421081
Sam Saffron
You say: "This means data obscured by MD5 is unsafe and could be reproduced.", this is wrong, if it was true MD5 would be the best compression algorithm known to man. MD5 is vulnerable to collision attack. Meaning its very easy to find to hash Y and X that have the same hash. MD5 is not vulnerable to pre-image attacks ... read about it here: http://en.wikipedia.org/wiki/Preimage_attack
Sam Saffron
+13  A: 

Take home point: Use bcrypt for password storage.


MD5 and SHA1 are different hashing algorithms. MD5 "compresses" any stream of bytes into a 128 bit value. SHA1 compresses any stream of bytes into a 160 bit value. This compression only goes one way. If you give the hash of a random stream of bytes to someone , there is no theoretical way for them to go back to original stream of bytes. This is because of the pigeonhole principle. You can not fit infinity into 128 bits.

The MD5 algorithm is slightly cheaper to compute, however MD5 is currently very vulnerable to collision attacks. Similarly SHA1 will most likely be very vulnerable to collision attacks in a few years since there are now some attacks, security experts consider SHA1 broken since collision attacks are feasible.

For some uses MD5 and SHA1 are perfectly fine

Say for example you were looking for duplicate files in a file system. One (slightly inefficient way) would be to calculate a MD5 hash for every file in the file system. If you find 2 duplicate MD5 hashs, you have a duplicate file. This is a fact because there are no MD5 collisions in the wild, they have to be painstakingly generated.

For some uses MD5 and SHA1 are very bad hash functions to use.

(keep in mind that real world cases where collision attacks are bad are very elaborate). Say you are writing an email-signing-service that works like this:

  1. User sends you an email
  2. You read the email
  3. You hash the message and store the hash in your database.
  4. Anyone can interrogate a public API on you site that takes as an input a body of text and returns a boolean that says weather you have seen this message before or not. The way that works is that you hash the message and compare it to the list of hashs in your db.

If you were using MD5 someone malicious could generate two messages GOOD and EVIL, give you the good one to look up and later on pretend that you saw the EVIL message.

To overcome this, you could use a private salt or a stronger hashing function like SHA256. SHA2 based hashing functions are available for PHP.

Keep in mind MD5 and SHA1 are not even theoretically vulnerable to preimage attacks.

For some uses MD5 and SHA1 are the wrong tool for the job.

Take for example password storage. The trouble with MD5 and SHA1 are that they are really fast, they are designed that way. A fast computer could hash millions of passwords a second.

With password storage, you calculate hash of a password combined with a known random string (to impede rainbow attacks) and store that hash in the database.

The problem is, that if an attacker gets a dump of the database, he can, quite effectively guess passwords using brute-force. Every combination he tries only takes a fraction of millisecond, and he can try out hundreds of thousands of passwords a second.

To work around this issue, the bcrypt algorithm can be used, it is designed to be slow so the attacker will be heavily slowed down if attacking a system using bcrypt. Recently scrypt has made some headline and is considered by some to be more effective than bcrypt but I do not know of a .Net implementation.

Sam Saffron
What do you mean by a place that the hackers can never get? When you need to check that someone has entered the correct password, you need the salt to make sure they've done so. But if you can access the salt from such a place, why can't hackers? I suppose you could store and compute everything on a separate, tamper-proof card, but then you might as well store the password database there as well.
Brian Campbell
You have a good point there Brian, I think maybe we should put a seperate question out there on how a bank should store its password. Im thinking something along https://www.opends.org/milestone1/page/UsingThePKCS11KeyManagerProvider should do the trick
Sam Saffron
-1 On the bcrypt recommendation. Why favor an unproven algorithm over battle-tested SHA family? You can also make SHA as slow as you want, or you can add a salt. The trade-off you describe is not advantageous, and as a security recommendation, potentially dangerous. I am surprised this answer got so many upvotes.
NullUserException
And on your second point (about the email API), that too can be defeated with salts. Why anyone would make such an API in the first place is beyond me. Finally it's interesting that you call SHA or even MD5 "broken." I haven't seen usage of the vulnerabilities found on MD5 in attacking a password store. Don't take this personally, but have you ever cracked a hashed password before?
NullUserException
@NullUserException ... hopefully this gives us an answer http://stackoverflow.com/questions/3722780/do-any-security-experts-recommend-bcrypt-for-password-storage
Sam Saffron
@Sam Good call.
NullUserException
A: 

Would it not be a better solution to prevent repeated password Attacks. EG:

Controller Program would set session variables and pass these to a HTML form.

Set Hidden form name="MD5 hash" value="different MD5 hash" Set session variables for form name and value.

When form is submitted, compare session variable to what is submitted from form.

You need the Session(MD5 hash,post) to get the session (different MD5 hash) to validate the form. Each attempt to submit a form creates new form name and value variables. This eliminates CSFR and brute force possibilities. Try and guess 2 MD5 hashes.

Brent Thirsk
A: 

SHA-1 is more secure than MD5. Google and other gaints are moved from MD5 to SHA-1 due to the weakness of MD5. So, SHA-1 is always preferable choice...

Sriram