I’m developing an Android app with a MySQL database for storing user login credentials. I’m using jBCrypt for hashing passwords before storing them in the database. On registration, the password is hashed on client-side as follows:
String salt = BCrypt.gensalt();
String hash = BCrypt.hashpw("password", salt).split("\\$")[3];
salt = salt.split("\\$")[3];
hash = hash.substring(salt.length(), hash.length());
In this case, BCrypt.hashpw()
will give me the hash
$2a$10$rrll.6qqZFLPe8.usJj.je0MayttjWiUuw/x3ubsHCivFsPIKsPgq
I then remove the params ($2a$10$
) and store the first 22 characters as salt and the last 31 as hash in the database:
------------------------------------------------------------------------
| uid | salt | hash |
------------------------------------------------------------------------
| 1 | rrll.6qqZFLPe8.usJj.je | 0MayttjWiUuw/x3ubsHCivFsPIKsPgq |
------------------------------------------------------------------------
Now, whenever a client wants to log in, they enter their username and password and only the salt is returned from the database. The client calculates their hash by calling BCrypt.hashpw()
with their salt:
String salt = "$2a$10$" + returnedSalt;
String hash = BCrypt.hashpw(“password”, salt).split("\\$")[3];
hash = hash.substring(salt.length(), hash.length());
giving me:
hash = "0MayttjWiUuw/x3ubsHCivFsPIKsPgq"
which is equal to the hash stored in the database. The client then sends the username and the calculated hash back to the server. If they match, the user gets logged in.
I know that I can simplify this process by fetching the entire BCrypt hash directly and compare it with the given password with
if (BCrypt.checkpw(“password”, bCryptHash))
// match
but it feels wrong to send the entire hashed password to the user to perform the check.
I understand that it is preferable to hash the passwords server-side, but is there something wrong with this solution? Am I missing something?
Say that I have an unencrypted HTTP connection between the phone and the server. Would this be a secure solution?