0

Picture a state of the art implementation of a website registration and login system.

I'm interested in analyzing what a defender gains and loses by feeding the user password to a key-stretching KDF function (e.g. argon2).

Let's start from the basis.

Given a hash function H and a password Pwd, performing h0 = H(Pwd) and sending h0 to the server is pretty useless. However, if Ks is a per-site unique value (some use the hostname but a random unique value is more portable) then h1 = H(Ks || Pwd) turns a possible shared secret (Pwd) into a per-site unique secret (h1).

An attacker knowing h1 from site A can still impersonate the user on the specific site but it cannot use h1 on, say, site B. Even if both sites use the same client-side processing of Pwd.

As standing the scheme is weak, H is prone to many attacks, a quick analysis turn H into full-blown KDF with key-stretching with the server sending all the necessary entropy (or just set minimum requirements for the UAs).

So, by sending h2 = KDF(Ks, Pwd, costs_params, salt) to the server, we make sure the effective password used to register/login on this website is unique and resistant to usual attacks on stored passwords. An unrelated but useful reminder: server-side h2 is still "hashed" (i.e. KDF with KS) to prevent turning a leak into an easy impersonation of the users.

I've not seen this scheme implemented in any framework or even raccomended as far as I know. Why? Should I start implementing/requiring it?

I tried to write down a list of cons and pros.

Cons

  1. The server cannot enforce a password policy. My opinion is that most password policies are harmful but the server should at least do a few checks. In particular, check the length and if the password is in the n-most-used-passwords list. However, the length check can be done client-side (at the cost of possibly letting "smart" users bypass the check).
  2. This extra processing prevents credential stuffing only in the case the attack can solely intercept TLS traffic passively. If the attacker can control the user device, or the server, or tamper with TLS traffic this is all worthless. It's worth noting that if an attacker can read the TLS traffic they already have access to the user's sensitive information (including authentication tokens). This reduces the usefulness of this client-side processing.
  3. It consumes (variable) client-side power. JavaScript implementations are sufficiently fast but they have great variability and the user may not be happy with the increased power consumed. It's not much about time as much as about battery life nowadays.
  4. It's an extra moving wheel. I have the feeling (under discussion) that all this processing is doing is adding an extra "protection" on top of TLS but without adding too much (see point 2). Less moving parts are better. We do something similar server-side though, but in that case, the weak link is the server, which is a single-person business, while in this case, the weak link is TLS which is all people business. Plus unique password generation can be handled by encouraging the use of password managers. All this gives me a feeling of "reinventing the wheel".

Pros

  1. It prevents credential stuffing even if somebody is sniffing TLS. This is the only bullet but it is very appealing.

There already is a very similar question: Secure authentication: partial client-side key stretching... please review/criticize my idea but the answer focuses only on con #3 which, 8 years later, don't really hold anymore.

Personally, I have the feeling that theoretically it is useful but in practice the attack surface removed is very small and if one considers TLS compromised then all bets are off (just as if the standard crypto is broken).
Yet maybe I'm just old and not receptive as I should be.

Reiterating the question: Should we start requiring client-side key-stretching KDF processing of the user password as we require server-side?

Margaret Bloom
  • 1,211
  • 9
  • 12
  • *"Kp is a per-site unique value (i.e. a pepper, some use the hostname but a random unique value is more portable)"* - a pepper is a secret. The hostname is not a secret, thus it does not fit the description of a pepper. Even a random unique value is likely not secret because it must be always the same for a site and it must be known before logging in - thus also known to the attacker. – Steffen Ullrich Aug 04 '22 at 19:21
  • @SteffenUllrich My bad, you are right (although not very helpful considering the word "pepper" appeared only once in the question and was kind of irrelevant). I corrected the question, thank you for pointing this out. – Margaret Bloom Aug 05 '22 at 08:08
  • Similar question: https://security.stackexchange.com/questions/254820/to-lighten-server-load-is-hashing-a-client-side-argon2-hashed-password-with-sha – mti2935 Aug 05 '22 at 09:26
  • @ThoriumBR Unfortunately it doesn't. The answers to that questions are naive and don't address any of my points. – Margaret Bloom Aug 05 '22 at 10:30
  • @MargaretBloom, wrt `So, by sending h2 = KDF(Ks, Pwd, costs_params, salt) to the server` - where would the salt be stored? Presumably, on the server. If so, then you would have to work out some protocol for the client first obtaining the salt from the server, then performing Argon2. At that point, this begins to look very much like PAKE/SRP, so why not use PAKE/SRP, which offers many other benefits (including mutual authentication between client and server, and more, see https://security.stackexchange.com/questions/242811/alternatives-for-sending-plaintext-password-while-login/242824#242824. – mti2935 Aug 05 '22 at 10:42
  • @mti2935 Can't the client ask for the salt given the username? As I commented in your answer, salts are not supposed to be secret, just unique, aren't they? Also, does SRP work registering a new user? People advocating for this scheme say it's an additional security layer on top of TLS because `h2` is unique per site even if `Pwd` is not (in case one can sniff TLS). – Margaret Bloom Aug 05 '22 at 11:12
  • @MargaretBloom, yes to all. – mti2935 Aug 05 '22 at 11:15
  • @mti2935 Thanks, that makes sense indeed. If somebody really doesn't trust TLS and wants a per-site unique password they should use SRP instead of a half-baked solution. Thanks for helping me pinpoint what's wrong with that scheme, I didn't remember all the properties of SRP. – Margaret Bloom Aug 05 '22 at 11:25
  • @MargaretBloom Glad this helped. Good luck with your project! – mti2935 Aug 05 '22 at 13:48

0 Answers0