Set a hash, login with a password?

The issue that usually comes up when talking about client-side hashing is that an attacker who has breached the database can merely pass the hashes to the server to authenticate. However, this scheme doesn't allow use of the hash for authentication, just the initial account creation, so it doesn't fall into that trap.

I've seen this sort of thing used in the context of Apache htpasswd files; users generate a digest and send it on a relatively insecure channel (e.g. email) to the systems administrator, who then adds it to the server configuration. While a system involving basic or digest auth isn't the pinnacle of computer security, this shows that it's not an entirely novel approach, and has had at least some attention.

Given the description as you put it, I don't see any obvious issues. There can of course be implementation issues, like a bug that allows feeding the hash instead of the password for authentication. And since the initial connection isn't trusted, it's probably a bit easier for an attacker to obtain a password hash (that they can then try to crack or generate a collision for). But those aren't issues with the scheme itself, or major issues.


I agree with @Xiong Chiamiov, there isn't anything inherently wrong with this approach.

On the other hand, it doesn't provide much benefit to the standard approach (all hashing is done server-side), and there is definitely some risk in disclosing the hash to untrusted entities.

If the original client isn't trusted, this obviously does nothing, as the client could just log the entered password.

If the original connection between client and server isn't trusted, this only helps a little. A passive man in the middle still gained the hash and can try to crack it. An active man in the middle could change the hash to gain access, or could change the reply to the hashing policy to force a weak hash to gain the password (or force no hashing at all; or just inject Javascript or similar to read out the entered password).

So the only sensible use-case is limited mitigation against a passive man in the middle on initial signup. If I would encounter this, I would check how untrusted the initial signup really is, and if there isn't a more sensible approach than disclosing the hash.


Two nits

possibly after requesting the hashing policy - salt, which hash function, etc - from the server

I am not clear if this mechanism uses a per-user salt or a global salt. If it uses a global salt, it is vulnerable to a rainbow attack.

Server stores "99476bb..." in the database as the password hash for that user.

Because the hash was generated outside of the server, there is no way for the server to enforce any password complexity or length rules. They would have to be enforced by the app. Also, there is no way to check for password re-use.