I pop up every once in a while and since I'm dealing with the same thing myself I chime in.
I wouldn't use bcrypt on the client side, too much of an issue and as far as I know it wasn't designed to do hashing but to encrypt. Besides, everyone is going towards https so client hashing will become less of an issue.
So, use bycrypt yes but on server side only.
I liked the client side hashing, but could be hard to do on client side, because we would
need to pass costs and salts to client (if we use bcrypt). Or we use another algorithm on client
side, which could make things worse. Or we use stable values for this. Costs of 20, salt of blubb.
As long as we don't get hash collissions on the first round, this shouldn't be a big problem?
Besides that, client side hashing doesn't protect against mitm. Simply serving a evil js would
destroy all the benifits. Only scenario where this could help is if there's no ssl. But as soon
as an evil person can hook between server and user, this doesn't help anymore.
I looked into password_hash function, i think it's safe to use. Because in the resulting
hash there are information about the algorithm (bcrypt), the salt, and costs (some bcrypt
specific parameter which defines how many rounds of bcrypt shall be used to make brute
force attacks harder.) and therefore password_verify will take the right algorithm and parameters
to verfify the password.
Things to think about:
- how to define costs for bcrypt, Settings.php?
- How do we change the password values in running environments? We have to plan this for the future
(if the default hash algo changes) and for now.
EDIT:
Easiest thing would be to send the passwords always in plain text, on server side check if we have an old password saved with sha1, if so, hash it in the old way and verify it. If it's fine, hash it in the new way and update the value. If not, password's wrong, error message and so. If it's already with the new algo, just do password_verify.