3

I am making a login system, and when logging in the password currently gets sent from JavaScript to a PHP file.

In PHP I use the following piece of code to hash.

$hash = password_hash($_POST['password'], PASSWORD_BCRYPT);

How should I hash the password in JavaScript before sending it using POST?

I obviously do not want to affect BCRYPT's security.

Pradeep
  • 9,667
  • 13
  • 27
  • 34
Koen T.
  • 33
  • 1
  • 5
  • 2
    Hashing on the client side does not make it more secure. Use HTTPS to communicate, and use password hashing + salting on the server-side to store passwords. – Dave Chen May 29 '18 at 07:28
  • Do a password hash with MySQL, using SHA1 or SHA2, then compare against the SHA of the Client password to the database. Use SSL to protect data going over the line. – StackSlave May 29 '18 at 07:29
  • Hashing passwords in the frontend SHOULD be done regardless of using https. See here for an explanation: https://stackoverflow.com/a/21716654/43615 – Thomas Tempelmann May 16 '19 at 14:19

3 Answers3

5

What is done on the client side is not really controlled by you. What I mean is that even if you hash your password it's possible for a client to get the password before hashing/encryption.

var password = document.getElementById('login').value;
console.log(password); // It is as simple as it
//hash password...

Above a simple example to explain, the client could get the password like this, or someone else could get it using a XSS attack. You should do your best to protect your clients from XSS, but then you can't control what happens on the client side.

If what you fear is a Man In The Middle (MITM) attack, the most important thing is to use a TLS certificate with a correct algorithm (it depends on the OpenSSL version of your server).
In short, using HTTPS is what you should do to protect your clients from a MITM attack.

So according to me, it's not required to hash/encrypt the passwork before sending it.

Anthony
  • 2,014
  • 2
  • 19
  • 29
  • Thanks, this explains exactly my concern (and how wrong I was). – Koen T. May 29 '18 at 07:39
  • You're welcome! It's sometimes hard to understand that the client side is not safe. There is a rule _Never Trust User Input_, it is because the browser is not controled by you. So you should secure it as much as possible, but then it's not possible to be sure about it's safety. – Anthony May 29 '18 at 07:43
4

If you want, you can play with some bcrypt implementation client-side (search "bcrypt js", there is an example of implementation).

BUT, that means you must use the same salt value between server and client. This answer explains.

Therefore, if a client is compromised, your secret server salt value will also do.

BUT, what's your meaning ? If you think it's more secure to send and compare the hash instead of sending once plain password and hashing it server side, you're wrong. A man in the middle will stole password or hash either and will break security.

The right answer have been given in comment : You better use HTTPS for best security. At least, use digest auth if you can't use HTTPS protocol (What is digest authentication?)

Anthony
  • 2,014
  • 2
  • 19
  • 29
Bertrand
  • 1,840
  • 14
  • 22
1

without HTTPS nevermind doing such a thing on client-side, because they will obfuscate your code see your encryption algorithm anyway.

scetiner
  • 361
  • 3
  • 9
  • I do use HTTPS, but do you think I should not hash before sending it? Is it secure like this? – Koen T. May 29 '18 at 07:28
  • If the algorithm is on the Client, anyone can see it, so it will do no good to attempt a Client Side encryption. – StackSlave May 29 '18 at 07:33
  • Since you have to use a secret key, it will be stored at client somehow, which mean you gave everything to them. just use form post and keep it in your SSL channel, by the way you should definitely use encryption during database access. – scetiner May 29 '18 at 07:33
  • Thanks for the tips! – Koen T. May 29 '18 at 07:39
  • There is so much misunderstanding about how hashes and encryption works. If course, you would not encrypt with a symmetric key. You'd either use asymmetric technics where the sender that encrypts the data has only the public key, and only the server with its private key and see what was encrypted. Or you, even simpler, the hashing method, with using a salt (or nonce) means that an attacker can maybe see the hashed value but can't recreate the original password from it (that's what a hash is about) nor can he reuse the same hash if the server sends a nonce (google that) – Thomas Tempelmann May 16 '19 at 14:26