10

First I am very bad in cryptographic algorithms.

I found online that Argon2 is more secure than SHA-512, so I used it for password hashing.

There're recommended options for Argon2:

  • Memory: 4Gb
  • Iterations: 4 or more

On my ancient server it takes a little less than infinity for 100 users... So, I've decreased options to:

  • Memory: 100Mb
  • Iterations: 3
  • Threads: 4 (if it's important)
  • Type: Argon2i (recommended for password hashes)
  • Salt size: 20 bytes

These options are significantly lower than options that I found as recommended. So I was wondering...

Will Argon2 with my options still be more secure than SHA-512? Or should I switch back to SHA-512?

P.S. If my question is not clear, text me, plz, I will try to reformulate it

Bruno Rohée
  • 5,351
  • 28
  • 39
Denis Sologub
  • 203
  • 1
  • 6

3 Answers3

15

Argon2 is intentionally slow: slow-hashing functions are good for storing passwords, because it is time/resource consuming to crack them. In the case of Argon2, the hashing consumes memory, too. The tradeoff in your fine-tuning is that your hardware can calculate the hashes a bit faster, and an attacker would have the same advance to the same extent. Also, you just have to consume the resources once per login attempt or password creation, while someone cracking the hash must do it per every single try.

On the other hand, SHA-512 is not designed for storing passwords. Not only that it is faster on the hardware in question, but SHA-512 is way faster to calculate on GPU or specialized hardware, whereas Argon2 does not have this weakness.

user7761803
  • 127
  • 3
Esa Jokinen
  • 16,725
  • 5
  • 51
  • 56
  • 11
    Argon is slow but that is not the point of Argon (by multiple iterations you can also make SHA-512 slower): it has the ability to consume a configurable amount of memory which can make brute force attacks a lot more difficult as you can't perform may be 1000 attacks in parallel. – Robert May 11 '22 at 13:07
  • 3
    Slow doesn't necessarily mean processor cycles, but I've clarified my answer. – Esa Jokinen May 11 '22 at 15:16
11

Argon2 tuned to the max delay you can stand, if you must choose between the two - but the better answer may be: neither.

Multiple judges for the Password Hashing Competition - that selected the Argon2 family as its winner - have since acknowledged that once you tune Argon2 to be as responsive as indicated by UX studies for interactive authentication (<=500ms), it's actually worse than bcrypt from a defense perspective (better for the attacker, worse for the defender). This is because at those tuning levels, Argon2 is less resistant to parallel attack than bcrypt is when tuned to the same responsiveness.

So as long as you're OK with bcrypt's other limitations (max 72 characters, and avoiding nesting), bcrypt may still be a better choice, depending on your scale and threat model.

And either would be a better choice than both raw SHA-512 (because even high iterations don't sufficiently reduce parallelism) or sha512crypt (because it has its own issues).

Edit: some benchmarks that one of the other PHC judges (Steve Thomas) posted to support this claim.

Royce Williams
  • 9,318
  • 1
  • 32
  • 55
  • Thank you! I will learn more about bcrypt – Denis Sologub May 11 '22 at 17:30
  • 1
    Be sure to tune bcrypt to as high a 'work factor' as can be absorbed by your scale - ideally, cost 12 or 13 (whatever gets you closest to that 500ms as you can tolerate.) – Royce Williams May 11 '22 at 17:32
  • 1
    Excellent addition, not to limit this to the two algorithms given by the OP. – Esa Jokinen May 11 '22 at 17:49
  • If I need to use sha2 I would use PBKDF2(HMAC sha2) not Shacrypt. – eckes May 12 '22 at 01:03
  • The nesting seems to be PHP specific? Not something inherit to the bcrypt algorithm? – Maciej Piechotka May 12 '22 at 03:01
  • Someone needs to bop whoever did those "UX studies" over the head with a light mallet. 500 ms is **not** responsive; it's a good order of magnitude away from being responsive. – R.. GitHub STOP HELPING ICE May 12 '22 at 12:17
  • 1
    The context was that most users aren't surprised by login times that take longer than a generic page load, and that 500ms was the upper bound of refraining from surprising them. :D – Royce Williams May 13 '22 at 03:04
  • @MaciejPiechotka - not necessarily PHP-specific, but rather something that's sometimes done to work around bcrypt's 72-character maximum, and/or a side effect of "upgrading" from an unsalted hash to bcrypt. bcrypt(md5(pass)) and bcrypt(sha1(pass)) are common. Upgrade nesting/wrapping should be one-time, and upon the next successful auth, the wrapped hash should be replaced with pure bcrypt - see https://www.michalspacek.com/upgrading-existing-password-hashes for more context. – Royce Williams May 13 '22 at 03:09
  • 1
    @user1067003 Putting a faster unsalted hash inside a slower salted one opens up a very specific kind of attack called 'hash shucking' - which is non-intuitive for some, but makes some kinds of attacks much faster than the un-nested alternative: https://security.stackexchange.com/a/234795/6203 – Royce Williams May 13 '22 at 06:49
  • @RoyceWilliams: It may be true, may be not. None of your links provide any analysis or explanation, just statement. – mentallurg May 14 '22 at 18:57
  • @mentallurg Fair. Steve Thomas (one of the other PHC judges I mentioned, AKA Sc00bz) replies with benchmark detail in a couple of replies here: https://www.reddit.com/r/crypto/comments/l395nj/argon2_is_weaker_than_bcrypt_for_runtimes_1000ms/gkhcgtq – Royce Williams May 14 '22 at 19:09
  • @RoyceWilliams: It is better, but it is just **theory**. See the discussion in that thread: *"The advice you and Jeremy are stating is only backed by **theory**, not actually verified?"* – mentallurg May 14 '22 at 20:35
2

The other answers have already explained why Argon2d is better than SHA512 for password hashing, but I'd like to share some experience on tuning Argon2 for web server.

  • First, pick the Argon2 variant. Although the spec said Argon2i uses data-independent memory access, which is preferred for password hashing and password-based key derivation, I prefer Argon2id because it provides a balance resistance to both side-channel and GPU-based attacks
  • Second, pick the memory requirement, since a web server need to serve multiple users at the same time, use a low number like 4MB.
  • Third, pick the number of threads/degree of parallelism: 1 is a safe bet, since the web server should already use multiple threads to serve requests.
  • Forth, pick the number of iteration, the higher number the better, as long as the verification speed is not too slow for you: a value between 1 to 5 should be good enough.
  • For salt size and output size, just use your hashing library's default value. If you want to customize, a 16 bytes salt size and 32 bytes output size is good enough.
Kien Truong
  • 121
  • 3
  • Thank you, it means my options are not so bad as I thought! – Denis Sologub May 12 '22 at 11:25
  • Tuning the values this low is exactly what makes Argon2 less resistant to cracking than bcrypt is. – Royce Williams May 14 '22 at 19:04
  • 1
    It's resistant enough. The argument that Argon2 is worse than bcrypt when tuning to be faster than 500ms has a lot of holes in it; since speed is dependent on hardware: what run slower than 1s in one system can run in under 500ms in another system. – Kien Truong May 16 '22 at 01:15
  • While your answer looks interesting at first glance, it gives almost no reasoning for the values you decided to use. Your solutions may be either really good or can be terribly bad. And nothing gives a hint how exactly one may check it easily. Only for the amount of iterations you proposed to test how fast it is. All others are just "random" numbers. – Victor Yarema Jul 18 '22 at 20:12