7

When it comes to hashing passwords, it is nowadays practice to do 100'000 or 200'000 iterations of SHA256/SHA512, or at least something in that ballpark.

But my question is, why is it not safe enough to just do a very small but unusual number of iterations that is unlikely to be guessed?

For example, let's say I use 153 iterations of SHA512 to hash the user passwords. Now a hacker breaches the database and steals all password hashes. They will never guess that I'm using exactly 153 iterations and they don't have access to the source code, also nobody will have created a lookup-table for 153, or 267, or 1139 rounds of SHA512 password hashes, correct? (Though lookup-tables are useless anyway if the passwords are salted before hashing)

18
  • 31
    Have you heard of Kerkhoff's Principle? It states that everything about your cryptosystem, except the key, should be assumed to be public. Other than that, SHA256 is not a password hashing algorithm because it is very fast.
    – Gamer2015
    Jul 29 at 11:25
  • 7
    Why would it be 1+2+3+...+n? If someone hashes for 100000 times, and after each iteration compares the result, wouldn't it cover all the cases from 1 to 100000?
    – pri
    Jul 29 at 12:01
  • 3
    He just needs to calculate 200'000 hashed to compare all the hashes from 1 iteration to 200'000. He can just use the intermediate values for the comparison
    – Gamer2015
    Jul 29 at 12:02
  • 16
    This question just seems to be a specific version of "why is security by obscurity bad?"
    – Herohtar
    Jul 29 at 21:19
  • 4
    @cssstudent It sounds like a great idea (just as all the other trickeries about changing public information of some hashing algorithm) until you realize that the hacker can just create an account themselves. I leave how that additional information will help figure out the details of the hashing algorithm to you.
    – Voo
    Jul 29 at 21:32
42

The idea of a large number of iterations is not to be part of the secret, but to take more time.

Having a database with a large number of passwords means someone will have a weak password, and it's trivial to test the dictionary of worst 100k passwords in minutes, no matter if you are using 200k iterations, or 153 as you are using. A dedicated password cracking device from 2018 achieved 9392.1 MH/s (mega hashes per second) doing SHA256, so trying 100 worst passwords from 1 iteration to 200,000 iterations would take the attacker just seconds to deduce how many rounds you are using. And that goes all your secrecy.

That's why you don't use SHA or MD5 for password storage: they are fast hashes. They are very good for checking the integrity of a download, or the data on Bitcoin blockchain, but not for password storage. And you should use a tunable hash for that, like Argon2 (as CBHacking reminded me).

Compare the 9392.1MH/s for SHA256 with 43551 H/s for BCrypt with Blowfish, and 124 H/s for Veracrypt PBKDF2-HMAC-Whirlpool + XTS 512 bit. It's not practical to do a dictionary attack with a large sized dictionary against a decent configured Argon2 password database.

The main point of the password hashing algorithm is that you can tune them to be as slow as you want without committing a self-inflicted DoS. If you put so many rounds that it takes 10 seconds for your server to process a login request, an attacker can hammer your server with login requests with bogus passwords and essentially kill it.

13
  • 4
    The point still stands: take 100 worst passwords, bruteforce from 1 to infinity until they get a match. It's very unlikely nobody would have a password on the "worst password list" and have an account at your service.
    – ThoriumBR
    Jul 29 at 12:12
  • 8
    Exact. That's why you use random unique salts for each user.
    – ThoriumBR
    Jul 29 at 12:16
  • 13
    Also in some cases they might have or be able to create an account of their own the site beforehand, and then all they need to do to figure out the hash count is to test their own password against their own hash.
    – ilkkachu
    Jul 29 at 14:33
  • 2
    Not at all. The attacker would only need to create an account, set his own password, and leak the database again.
    – ThoriumBR
    Jul 30 at 0:00
  • 4
    Good answer, but I must say: PBKDF2 and bcrypt are very old algorithms, and neither has a tunable memory cost (or a very meaningful one by modern standards, though bcrypt at least tried). The password hashing competition that ended five years ago crowned argon2 the winner, and it's been widely-enough used and tested since then that I really don't see a good reason to not use it. There are libraries available implementing it for basically every programming language.
    – CBHacking
    Jul 30 at 6:49
10

Because hashing is iterative, if the attacker doesn't know the number of rounds, they can compare the current result after each iteration to the target (stopping at some large limit like 216–218).

This approach falls squarely in "security through obscurity" territory, and undermines the purpose of iterating the hash.

0
3

In addition to the other answers about iteratively checking weak passwords until you get a hit for some account, consider this:

What if you already know one of the passwords in the DB? Perhaps it's yours, or belongs to somebody you know who agrees to help out. Perhaps it's from a breach on some other site, and the user re-used passwords (never do that).

If you're checking a specific password against a specific hash, it doesn't even have to be a weak password. All you need to know is the necessary iteration count, and that will be extremely easy to find by iterative testing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.