Edit: Updated to put more emphasis on the goal - peace of mind for the user, and not beefing up the security.

After reading through a few discussions here about client side hashing of passwords, I'm still wondering whether it might be OK to use it in a particular situation.

Specifically I would like to have the client - a Java program - hash their password using something like PBKDF2, using as salt a combination of their email address and a constant application-specific chunk of bytes. The idea being that the hash is reproducible for authentication, yet hopefully not vulnerable to reverse-engineering attacks (to discover the literal password) other than brute force if the server data is compromised.

Goal:

The client side hashing is for the peace of mind for the user that their literal password is never being received by the server, even if there is the assurance of hashing it in storage anyway. Another side benefit (or maybe a liability?) is that the hashing cost of an iterated PBKDF2 or similar rests with the client.

The environment characteristics are:


All client-server communication is encrypted.
Replayed messages are not permitted. ie. the hash sent from the client cannot effectively be used as a password by an eavesdropper.
Temp-banning and blacklisting IPs is possible for multiple unsuccessful sign in attempts within a short time frame. This may be per user account, or system wide.


Concerns:


"Avoid devising homebaked authentication schemes."
The salt is deterministic for each user, even if the hashes produced will be specific to this application because of the (identical) extra bytes thrown into the salt. Is this bad?
Authentications on the server end will happen without any significant delay, without the hashing cost. Does this increase vulnerability to distributed brute force authentication attack?
Rogue clients can supply a weak hash for their own accounts. Actually, not too worried about this.
Should the server rehash the client hashes before storing?


Thoughts?

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.
