While reading the Hashing topic of C# in a nutshell book,i came across the following quotes!
You can provide additional protection against dictionary attack by
“stretching” your password hashes—repeatedly rehashing to obtain more
computationally intensive byte sequences. If you rehash 100 times, a
dictionary attack that might otherwise take 1 month would take 8
years.
So I implemented it this way!
byte[] data = Encoding.UTF8.GetBytes("Password is 12345679");
byte[] hash = SHA512.Create().ComputeHash(data);
int temp=0;
while (temp < 100)
{
hash = SHA512.Create().ComputeHash(hash);
temp++;
}
Is the above code right? Will a dictionary attack really take 8 years or so to decipher?
In the absence of shortcuts (as noted by @Random832), one should expect it to take 100x as long to brute-force test something that has been hashed 100 times as one. If the attacker is looking at every sequence of characters looking for a hash that matches, then anything that makes that hash take longer is going to slow him down (or equivalently, use more computing power).
Continuing to steal from Random832, this is a “poor-man’s stretching.” It is adequate and useful, but if you have the PBKDF2 function available, that is preferred, since PBKDF2 is well-analyzed by cryptographers. In the strictest sense, your code above is a “Password Based Key Derivation Function” (PBKDF), but PBKDF2 is a specific one. EDIT: I’m not a C# developer by trade, but it does look like .NET includes a PBKDF2 function Rfc2898DeriveBytes.
Note the key phrase in the above text, though: “that might otherwise take 1 month.” The writer is assuming it would take a month to do the first, and 8 years is approximately 100 months. If it would have taken 1 minute to perform a dictionary attack on the first, you should expect it to take about 1.5 hours to do so on the second. There is no magic “8 years” here. It’s just 100x the first number, whatever that first number happens to be.
EDIT: One more thing to note about stretching. You should always salt before you stretch. Salting means you add a random series of bytes to the start of the password. You then encode that salt along with the hash result (the salt is not a secret). So rather than hashing “Password is 12345679”, you would hash “deadbeefPassword is 12345679” and you would then send “deadbeef” in the clear along with the final result. The reason you do this is because people choose the same passwords all the time. So if the attacker works out the result of hashing “Passw0rd!” then he could just check that result against your hash. Much cheaper. Similarly, if he had both Alice and Bob’s hashes, he could tell if they were the same or different. But with a random salt, you can’t do that, since it is almost certain that Alice and Bob will have their data hashed with different salts.