Client side password hashing

Hashing on the client side doesn't solve the main problem password hashing is intended to solve - what happens if an attacker gains access to the hashed passwords database. Since the (hashed) passwords sent by the clients are stored as-is in the database, such an attacker can impersonate all users by sending the server the hashed passwords from the database as-is.

On the other hand, hashing on the client side is nice in that it ensures the user that the server has no knowledge of the password - which is useful if the user uses the same password for multiple services (as most users do).

A possible solution for this is hashing both on the client side and on the server side. You can still offload the heavy PBKDF2 operation to the client and do a single hash operation (on the client side PBKDF2 hashed password) on the server side. The PBKDF2 in the client will prevent dictionary attacks and the single hash operation on the server side will prevent using the hashed passwords from a stolen database as is.


There are few time when client-side hashing is worthwhile. One such circumstance is when the hash process is computationally intensive, which can be the case with PBKDF2.

Addressing your concerns:

  1. Also avoid unvalidated suggestions about cryptography you find on the internet. (Disclaimer: I am not Bruce Schneier.)
  2. Deterministic salts aren't a problem--the only real requirement of the salt is that it is unique for each user. The salt's real purpose is to prevent a brute force on one password from turning into a brute force on all passwords in the case of a compromised database. Even if you were to store a random salt in your database right beside the hashed password you would still reach this goal, provided each users' is different.
  3. As I mentioned above, PBKDF2 is nice because you can arbitrarily decide the computational difficulty of the hash. You could select a c such that a single hash on modern hardware takes seconds--effectively eliminating risk of an API level brute force attack. (Of course, your client's might not enjoy such a long delay at login.)
  4. An users can choose simple passwords--they are only hurting themselves. If you wanted eliminate this risk, you would have the server generate the hash the first time, provided ithe password is going over an encrypted channel.
  5. Yes, and you will need to uniquely salt these as well. In the event of a database compromise, you want to ensure that the attacker doesn't get information that allows him/her to directly authenticate as any user on your system. One caveat here is that you do not want your server-side hashing to be computationally intensive the way your client-side hash is. If your server-side hash takes too much effort, you open yourself to a CPU-exhausting Denial of Service attack vector--an attacker simply spams empty password authentication attempts over Tor, passwords which your server has to try hashing before it knows they are fraudulent, eventually leaving you with an overwhelmed server..

If you hash the password on the client side, whatever the result is IS the password, so you're not gaining any real security. Any hack or information leak that would have revealed the plain text password will instead reveal the hashed password, which is the real password.

This shouldn't be confused with zero-knowledge authentication schemes, where an exchange of messages proves that the client knows the real password, without actually transmitting it.