Hacker News new | ask | show | jobs
by gpm 2790 days ago
It stops them from using the password to log in to your other accounts.

It stops a compromised server from silently leaking unhashed passwords.

It makes password hashing user auditable.

You could even do a call and response model to stop the hashed password to log in at all. Here is a primitive scheme for such a model (public key crypto probably enables more clever schemes, not sure):

- Upon signup, generate hashes of "$password$site$i" for i in 1 to 1000. Send these to the server and have the server hash them again.

- Upon login, after the user has entered their password into the box, send an integer from i from 1 to 1000 to the browser, have the browser send back the hash of "$password$site$i".

Now a compromised hash can only let you log in 1 time in 1000. Combine that fact with the other available signals for "is this who we think it is" and you should be able to reject people who stole the hash reasonably reliably. Meanwhile since you are still hashing the password on the server (again) you have lost literally nothing but a tiny bit of computation time.

4 comments

Use a password manager and don't reuse passwords. If your randomly generated, unique password has good enough entropy then why go through all of the trouble of the rest of the client side hashing?

There's nothing stopping you from hashing your own passwords client side and sending your bcrypt hash up to the server except some sites still truncate the passwords to 32/16 chars etc.

When you have the need for the level of security, client side hashing will not be as good as dedicated HSMs that many services now use on authentication.

Writing your own crypto flows can be extremely dangerous as you open yourself to all kinds of side channel attacks.

A password manager is a client side method that only works for people who opt into it, Google needs to deploy a server side method. Likewise with hashing my own passwords client side. HSMs.

As for writing my own crypto. Indeed, if anyone actually used the scheme I suggested they would be making a mistake. I wrote it not to be used but to demonstrate that we can do better in an easy to understand way. Unlike me, Google has the resources to read the papers, do the math, carefully implement this, and do it properly.

Keywords for how to do it properly include "zero knowledge password proof" and "password authenticate key exchange".

PS. It's irrelevant to this conversation, but putting all my passwords into one program has always struck me as a monumentally stupid idea. I use one for passwords I don't care about, I memorize unique passwords for passwords I do care about.

worshipping an arbitrarily contrived measure of password entropy makes for good security theatre, but there's a lot that goes into maintaining anything resembling actual security. How many people use "password generators" and trust that they'll come up with "random" words? What about that old saying about putting eggs in a basket?
> It stops a compromised server from silently leaking unhashed passwords

If you trust the site to deploy correct JavaScript to do this, then that's the same level of trust that they implemented password salting and hashing server side. You don't gain any robustness by moving this to JavaScript.

Your scheme is just a weak salting technique. You'd be better off with just using a longer salt and hash function.

I separately assume a salt is part of my hash function. Salts only help with rainbow tables (an admirable goal, but not my one here).

I can trust the site to deploy the correct javascript more than I can trust it not to steal passwords because

- That is auditable - it is impossible for a malicious site to do so without risking being caught.

- The HTML/JS can be served from static cloud storage that is far less likely to be hacked than the server running a DB verifying passwords.

> - That is auditable - it is impossible for a malicious site to do so without risking being caught.

Hardly. Minimization and obfuscation is trivial, and you can ensure the output is always different in order to defeat auditing. Not great for caching obviously, but 'auditability' is not achievable if the server is determined to fool you.

> - The HTML/JS can be served from static cloud storage that is far less likely to be hacked than the server running a DB verifying passwords.

Password are simply not where you want to leverage your security. If you can find a document example of a real threat that this approach would have mitigated, then I'll take it seriously.

So the malicious site can run risk assessment first and then if it thinks nobody's looking, send different code for hashing to this particular user.
This still feels vulnerable to XSS. Better would be to have browsers provide an API to do this so that $site is trusted.

The downside is not a tiny bit of computation time. It's also increased latency for the customer.

This is completely wrong. HTTPS is what secures this, not client side password hashing. If you don't use HTTPS, you can just get MITM'd to disable any kind of client side hashing.