First, make sure you read this answer to the question "Client side password hashing", paying particular attention to the last paragraph.
Also, please realize that client side javascript is going to be incredibly slow at PBKDF2 compared to good server side code. At least try to find a PBKDF2 implementation that uses HMAC-SHA-512 as a base.
That said, if you want to give the user peace of mind, that's fine; do the following:
- Client side PBKDF2 hashing for a known, "high" iteration count.
- Double bonus points if the user is allowed to select the iteration count themselves!
- I put high in quotes because I doubt your javascript code's going to be fast enough to do tens or hundreds of thousands of iterations in the time you can get enough of your user base to accept, particularly on cheaper mobile devices.
- A good hash of the username and password as a salt isn't great, though it's better if your code pads the username out to the maximum possible length and puts it first.
- That way, "user1" and "password" don't make the same salt as "user" and "1password"!
- There is, of course, no maximum length on the password except what's caused by your back end software; SQL Server, for instance, has an 8000 byte maximum on "less inefficient" string work.
- Send that hash by itself to the server
- which then DOES generate a cryptographically random salt of 12-16 bytes
- and then uses PBKDF2 with a much higher iteration count to hash the hash passed in
- again hopefully HMAC-SHA-512 for the 64 bit operations to lessen the proportionate advantage of offline GPU attacks.
- because then someone who gets your leaked password database still has to do the work of an attack against a password hashing function to log in, rather than simply sending the client-generated hash they stole and having it be accepted as-is.
Remember with PBKDF2 password hashing in particular, never ask for an output size larger than the native base hash's output size. Smaller is all right if you're really, really concerned about storage; for instance, requesting only 32 bytes of PBKDF2-HMAC-SHA-512's native 64 byte output.
- 20 bytes for SHA-1
- 32 bytes for SHA-256
- 64 bytes for SHA-512