2

This is just a thought experiment. I am trying to get an understanding on when we need password hashing functions and when they don't bring any benefits (eg. to save on calculation cost).

I know that password-hashing-functions are to be used when storing password verifiers as passwords usually have low entropy. What about high-entropy secrets? Is it sufficient to salt and hash them with a normal modern hashing algorithm or should I still use a password-hashing-function to increase calculation time and memory?

Example: User uses a cryptographically secure RNG to generate a 256-bit secret which he then uses as 'password' to sign up. Is it good enough to store a salt and the sha256-hash of the salted password to compare against in the future?

Gamer2015
  • 707
  • 5
  • 12
  • The reason for hashing passwords is not because they are weak... – schroeder Jan 18 '22 at 17:05
  • 1
    OP, you might want to have a look at SRP. With SRP, the server stores a verifyer that is used to verify that the client has knowledge of a secret (password). It does this without the password (or password-equivalent) being sent over the wire; and there are a number of other benefits, such as mutual authentication, as well. See https://security.stackexchange.com/questions/242811/alternatives-for-sending-plaintext-password-while-login/242824#242824 for more info. – mti2935 Jan 18 '22 at 17:37
  • 1
    The problem with simply hashing a password using a hash function like SHA256, without salting, is that - if the password is low entropy (e.g. on a list like rockyou.txt), then it is very easy for an attacker to use a rainbow table to crack the password. Salted hashing makes rainbow table attacks much more difficult. See https://stackoverflow.com/questions/420843/how-does-password-salt-help-against-a-rainbow-table-attack for more info. If the password is randomly generated, salting may not be so important, but, I don't see what the downside of salting would be, even for high entropy passwords. – mti2935 Jan 18 '22 at 18:01
  • Good luck entering 64-hex characters :), well passwords manager can do this of course. The only problematic part that can be seen directly is this; can you guarantee that all of the users behave the same? Risk management must handle all of the users, not only the experts. Well, it turns out that cryptographers all also bad password users contrary to the beliefs. – kelalaka Jan 18 '22 at 20:58
  • @kelalaka I don't know if there are issues with that but would it not be possible for the server to generate a password and send it back to the user? I'm not familiar with acutally implementing security systems, but it would be the first thing that comes to my mind .. – Gamer2015 Jan 18 '22 at 22:45
  • I won't accept that. Even browsers can do this for the users. Why should a server do this? Temporary, yes, long-term, no! – kelalaka Jan 19 '22 at 11:36
  • @kelalaka Ad "Why should a server do this?": This was the first solution that came to mind where I can control the process of generating the secrets. When even a browser can do this reliably for the users, and therefore any native application as well, why did you pose your question in the first place? Is that not a solution to the problem? If I cannot trust a browser or native application with generating a sufficiently random secret, what solution can there be other than generating it on the server? – Gamer2015 Jan 19 '22 at 13:29

3 Answers3

1

This is the well known security/cost balance for the choice of a hashing algorithm:

  • the more resource consuming the algo is, the more resilient to brute force attack [assuming the hash has been leaked]
  • the less resource consuming the algo is, the more users can be accepted on a server

When you have a stateful application, the common assumption is that the login operation only scarcely occurs, and that spending time there is not a problem.

But it is true that the computation cost is commonly tweaked depending of the security requirements, and the expected load of the system.

You are true on one point: the total cost of a brute force attack is the product of the algorithmic cost of the hashing algo by the password entropy.

The problem in deciding to use a fast hashing function and hoping high entropy passwords is that you have little control on how the end user will choose its password. Because typed passwords normally have to be simple enough for a human being to be able to remember them, and type them with no typo - I cannot hope typing a 64 characters password with no typo...

A possible alternative is to use stored tokens. As they are not expected to be hand typed, the size is not a problem and you can safely use a fast hashing function. You only expect the user to securely store them, but after all it is their concern. This is for example used on GitHub. And as a GitHub user, I know that the security of my account is limited by the security of the machine/application that stores my tokens.

Serge Ballesta
  • 25,952
  • 4
  • 42
  • 84
1

What about high-entropy secrets? Is it sufficient to salt and hash them with a normal modern hashing algorithm or should I still use a password-hashing-function to increase calculation time and memory?

Example: User uses a cryptographically secure RNG to generate a 256-bit secret which he then uses as 'password' to sign up. Is it good enough to store a salt and the sha256-hash of the salted password to compare against in the future?

Yes, but in practice you don't know that's what a user did, so you'd run it through a password hashing algorithm anyway.

However, for high-entropy things where you do control the generation (or at least know the process used), it's quite reasonable to use a single iteration of a secure (but fast) hash algorithm, such as SHA2-256 or SHA3-256. You don't even really need to salt it; salting is to defeat rainbow tables and make duplicates look different, but nobody can make a rainbow table for even 128-bit-entropy values, and duplicates are functionally guaranteed to not happen (GUIDs are not quite 128 bits of entropy, in fact). Some examples of things where this is a reasonable approach:

  • API keys (essentially passwords but by machines for machines, not intended to be human memorable or even necessarily printable)
  • Opaque session tokens
  • Refresh tokens (typically paired with JWTs)
  • Password reset tokens (typically transmitted in a URL as hex or base64)
  • Cryptographic keys (if you're just checking to see if a user-supplied key is correct before using it for a bunch of encryption/decryption)

The reasoning behind this being OK is quite simple. Passwords get extra hashing because they're somewhat predictable; while in theory a reasonable-length password could be hundreds of bits of entropy, in practice it's more like dozens. Making the password hashing a million times as expensive is, in terms of the difficulty of brute-forcing the hash, like making the password have another 20 bits of entropy. BUT: that's still only going to get you from maybe 40ish bits of entropy (if it's a quite good password; less if it isn't) to the equivalent cost of 60ish bits. That's still over a quintillion times less work than trying to brute-force a 128-bit value. Similarly, passwords get salted so that they'll have unique hashes and you can't precompute them, but all that the salt is doing is adding some amount - typically 64-128 bits - of entropy to the password (and then storing that extra entropy in plain text, so it doesn't actually make brute-forcing any harder). A high-entropy (128+ bits of entropy) value already has more entropy than a typical password + a 64 (or plausibly even a 96) bit salt; collisions are just not going to happen, and precomputing is literally impossible because there isn't enough storage on the planet to hold the table, nor enough compute on the planet to generate it.

CBHacking
  • 42,359
  • 3
  • 76
  • 107
0

It depends on the quality of other secrets of that type. If the secret is high entropy, but it's stored as a password and other secrets are typical low entropy passwords, then you should use a normal password hashing function like Argon2. That's because you don't want to make it easy to guess the weak ones, even if there are strong ones like the ones you've described.

If all of the secrets of its type are high entropy (that is, having at least 128-bits of cryptographically secure randomness), say, because you generated random tokens for users of your API, then you can use a salted hash because it is computationally infeasible to brute force. HMAC with a strong hash function like SHA-2, SHA-3, or BLAKE2 is a great way to do this (as are other strong MACs).

bk2204
  • 8,695
  • 20
  • 19