After all, an attacker does not need to recover the password from the hash, all he has to do is capture the hash and replay it.
Also, tptacek made a few interesting comments about client-side cryptography:
http://news.ycombinator.com/item?id=1755713
http://news.ycombinator.com/item?id=1756394
At this point, I'm less worried about somebody getting access to some random startup I signed up for than I am about them using the leaked password to gain access to my other accounts.
(I've recently changed my password scheme to using a different one for every service, but this just puts me within a minority.)
Doesn't http://en.wikipedia.org/wiki/Digest_access_authentication do this? Also the server could store the nonce in a session.
If the salt is stored on the server, in a login.php script for example, and there is (just) a database compromise then an attacker will be at a disadvantage because they will need to figure out the salt first before cracking any of the passwords.
In fact, this is something being ignored here quite a bit. A number of potential attacks only lead to the database - or part of it - being exposed. If you have a large enough salt stored in your unaffected code base then an attacker is going to have a hard time.
Hashing ≠ Encryption.
Unlike encryption, where an encrypted message is intended to be decrypted by a trusted party, a hashed password is never intended to be 'unhashed'. Rather, the hash of the password supplied by the user is compared against the hash value stored in the database. Given a sufficiently strong password P, it should be computationally infeasible for anyone to compute the value of P from hash(P).