I am developing a small REST API with Lumen and a Electron/JS client. I do have a LoginController that should authenticate the user and return a JWT token when successfully logged in.
The server saves a bcrypt password in the database.
How should the client transfer the password to the server?
I tried to bcrypt the password on the client side and send it to the server, but I cannot compare two hashes, as they are different when salted.
To compare the hashed password in the database with the password the user has entered in the client application, I've to transfer the password in plain text. Is that really the way to go? I'll always need the plain password on the server for comparison?
One improvement would be to send a (not salted) SHA256 hash to the server. But this also means, that the server treats the SHA256 hash as plain password and therefore has to store the bcrypt of the SHA256 hash in the database.
Could one please describe the step how the client should send the password to the server in more detail?
If you are using a proper implementation of HTTPS using a strong ciphersuite, the password should not traverse in plain text. For any hashing algorithm to work, you will need the original. You should not use SHA, MD5, etc for hashing passwords as they are easily brute force-able. If you are really concerned about haveing your server handle the plain text password for a few milliseconds in ram to compare the hash, the only alternative I could see is building a asymmetric signature verification where the server asks the client to sign a unique string and verify the signature using the public key but that will hinder your application’s usabiliy and security of your implementation would be unknown as you are rolling your own cryptography which is not typically a good idea.
TL;DR: If you are using HTTPS (which you should be, it’s 2018 - Certificates are free), you do not have to do any hashing/funky stuff on the client side. Just verify the raw password against the bcrypt/argon hash stored in the DB. If you are new or don’t know what you are doing, stick with Laravel’s implementation for authentication.
I am using HTTPS with a certificate issued by LetsEncrypt.
When I got you right, it’s ok to transfer the password as it is, as the connection is encrypted anyways. The server receives the password as plain text and then can verify it against the bcrypt password stored in the database.
Is my small summary correct?