1

I wanted to know if the process of hashing a hash would help stop attacks to it (brute-force I think) when used with salt as well. So my code:

function hash_password($password, $salt, $site_key) {
    $hash = hash('sha512', $password . $salt . $site_key);
    for ($i=0; $i<1000; $i++) {
        $hash = hash($hash);
    }
    return $hash;
}

From what I can work out my code would be secure because it stops rainbow table attacks by using salt, and stops brute-force attacks by iterating the hash.

Would this iteration actually make brute-force attacks much harder? And if so how much would it affect the performance? (how long would it take to hash 1000 times, I heard someone said you should iterate the hash until it takes 200ms)

Does doing this emulate the behaviour of an algorithm such as bcrypt?

Andy Lobel
  • 3,356
  • 9
  • 31
  • 40
  • I've seen large-company web app security requirements state that a password hash loop needs to execute for a full second of server time. Took me 10,000 md5 iterations to fulfill that requirement. o_O – Matt H Jan 03 '12 at 19:22
  • Possible duplicate of [Double hashing security](http://stackoverflow.com/questions/1225528/double-hashing-security) ... and here are some reasons why people don't do this: [Why do people think that this is bad way to hash passwords?](http://security.stackexchange.com/questions/5586/why-do-people-think-that-this-is-bad-way-to-hash-passwords) –  Jan 03 '12 at 19:22
  • 8
    This loop is completely redundant. You're just calculating the same hash 1000 times. – Will Vousden Jan 03 '12 at 19:23
  • http://www.openwall.com/articles/PHP-Users-Passwords – hakre Jan 03 '12 at 19:23
  • @WillVousden is my code right now? – Andy Lobel Jan 03 '12 at 19:42

2 Answers2

8

Yes, it does, for a simple reason. Hashes were built for speed, not security (as it is often used to calculate checksums for large files). Therefore, a computer with a strong CPU (or a hacker using a GPU) could brute force your code with let's say 1 billion hashes per second.

If you make sure your hashing algorithm is slower (by iterating over it a thousand times), the same computer would only be able to do this algorithm 1 million times per second, and not a hundred. So if it took the attacker 60 hours to crack a password with brute force, it would now take 60,000 hours which is nearly 7 years :)


However, your code does not implement it correctly, you are preforming the same action over and over, where you should hash the hash you got in the previous hash, plus add some security characters (usually the iteration index).

while (i < 1000) { hash(somehash) } //wrong
while (i < 1000) { hash = hash(hash . i) } //correct.

PHP already has this functionality built in for you! Using crypt() in conjunction with CRYPT_BLOWFISH (a.k.a bcrypt), You can do input your password and salt into the function, and get a finished hash, after iterations and everything. For more information, See this question.

Community
  • 1
  • 1
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • 1
    If you want to foil brute force attacks, you're better off using something like bcrypt: http://codahale.com/how-to-safely-store-a-password/ – Will Vousden Jan 03 '12 at 19:37
  • kool thanks i know i got the code wrong am tired lol thats what i wanted to know about the 7 years thing xD how long will it take to do it when a user logs in? – Andy Lobel Jan 03 '12 at 19:37
  • 1000 times slower hashing, which would mean about 1 millisecond (that's 0.001 second) longer :) – Madara's Ghost Jan 03 '12 at 19:49
  • 1
    Does this increase the risk of collisions? – benekastah Jan 04 '12 at 07:00
  • 1
    No, it doesn't. The output of the final algortihm is a SHA1 string, which will have the exact number of possible outcomes as any other SHA1 string, so no, no increased collisions :) – Madara's Ghost Jan 04 '12 at 17:04
  • @truth is it just your 'while' loop that dosnt increase collisions or does my for'' loop work aswell ;p lol :-) – Andy Lobel Jan 04 '12 at 23:05
  • All loops are while loops, the for loop is only a shorthand. No loop will increase collisions. – Madara's Ghost Jan 05 '12 at 15:00
  • Yes, it does increase risk of collision, which makes brute-forcing easier. http://www.iacr.org/cryptodb/archive/2004/CRYPTO/1472/1472.pdf – Ryan Ward Valverde Apr 05 '13 at 20:32
5

The code you have there simply rehashes the same thing over and over again. If you look at $hash after the first iteration and after the last iteration, you will see that they are the same.

This is why we just use things like bcrypt. If you try to implement it yourself, you're very likely to do it wrong :)

Eric Petroelje
  • 59,820
  • 9
  • 127
  • 177
  • 1
    @Andy - Sorry, my point wasn't really to pick on your code, just to point out that when it comes to hash strengthening with iterative hashing, there is already a good solution out there (bcrypt). Trying to re-invent that is likely to leave you with a worse solution (no matter how good a programmer you are) – Eric Petroelje Jan 03 '12 at 19:47