Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Also you can do the stretching in the browser client (“server relief”) without losing security. Historically this would have meant a big performance penalty (and thus an advantage for attackers, who don't need to use your code) but JS and wasm are fast enough now that the price is fairly low.


If you’re going to do this, make sure you still hash the client’s hash output on the server (you can use SHA-2 in this case since the client’s hash output will effectively be high-entropy if salted). Otherwise you will be vulnerable to a “pass the hash” attack where an attacker in possession of your stored password hashes simply passes the hash to login.


I didn't think hashing the hash would be helpful here, and couldn't think of a way to mitigate against this attack.

After reading more it seems the only mitigation is Layers of Security.

https://en.m.wikipedia.org/wiki/Pass_the_hash#Mitigations


No, hashing the hash solves the problem.


It's important to understand why this is so: it's because the hash is big, so while it might be possible to mount a brute force preimage attack against a password, it is not practical to do so against a hash. So hashing a hash (once) is secure even though hashing a password (once) isn't.


Almost. That construction is still vulnerable to chosen input attacks without inner and outer padding, which is basically rediscovering HMAC, which also isn’t suitable for storing passwords. Don’t roll your own crypto if you don’t know what you’re doing. Use a PBKDF like argon2, scrypt, bcrypt or PBKDF2 as they are intended because they are far, far stronger than hashing a couple of times.


I believe what we’re discussing is having a client compute a PBKDF of the password, and then having the server hash the PBKDF output one more time to obtain the thing that’s actually inserted into the database. The idea is that if the database leaks, the attacker gets H(PBKDF(password)) which is hard to bruteforce due to the PBKDF, and can’t be used directly as a login token because of the extra H(). I don’t see where this would be subject to a chosen input attack.


I see, clever. Thanks!


It's not server relief, but there's also a technique called delegated hashing, i.e. allowing the client to do part of the work of computing the actual hash. This was one of the main selling points of the Makwa candidate for the password hashing competition.

It did not win, and I believe it is only CPU hard and not also memory hard unlike argon2. Nevertheless techniques to do this have been explored academically and might make it into future designs.

In case it isn't obvious, please continue to use argon2 (I'm just mentioning this as a point of interest).


Lots of advice in these threads and no one has mentioned anchoring yet so I'll staple it here; if you're a big company who can afford an HSM and the overhead of the key ceremony stuff to manage it (managed stuff like AWS cloud HSM simplifies this a fair bit) a great option is using an HSM as an anchored one-way function.

For whatever reason this seems to be seldom discussed but the general idea is as follows in hand-wavey fashion:

Set up HSM with a non-exportable symmetric key, set key usages to "encrypt only" and as one step of the hashing scheme you use, encrypt your hash through the HSM. Protected HMAC key would work too.

The result is that an attacker who compromises your password db cannot perform offline attacks on your passwords anymore - they now need to do key extraction on your HSM or remain in your infrastructure and keep running guesses through the HSM where it is relatively easy to monitor what is going on and they can't do a bajillion operations per second anymore.

Wish everyone running large user dbs like yahoo or linkedin etc applied anchoring to their password hashing - it's a relatively simple measure for an org "at scale" to make hash dumps alone useless.


Fair warning, mine isn't advice, just a comment about a technique that requires experienced cryptographers to use. I wouldn't attempt to use it myself :)


Can you elaborate? This doesn't sound right to me but I don't know much about this.


It is indeed surprising; it took me a long time to be sure it was safe. Google “server relief”.



That is pretty interesting, but doesn't actually offer up a solution that provides server relief, unless I missed something. In every case they still require that HSrv be a slow hash function.


My take away was that the server relief comes from reducing the ability of clients to trigger disproportionate amounts of server resource consumption.


I don’t see how that follows. If HSrv is expensive or slow, a malicious client could just submit nonsense hashes that only look like they might have come from HCli - the server shouldn’t be able to tell the difference.

Requiring client-side JavaScript for your login system seems fraught. I would much rather have an approach that does server side hashing exclusively, but gates it behind some kind of DDoS protection or rate-limiting.


You do the slow (bcrypt, argon2 or whatever) hash in the browser, and then the server can do the hyper-fast hash (SHA256).

You can still flood the server, but you're flooding it with things that take microseconds to compute, instead of 50ms.


That's not what the article states, though it's not very explicit about why you shouldn't do what you suggest.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: