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?
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.
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 :)