3
votes

I'm putting together an android client (and possibly in the future iOS, web portal, etc) and php mysql server. Server side I am currently using the PHPass library to hash and salt the incoming passwords.

Should I make the client send plain text passwords over HTTPS/SSL or should the client do some form of hashing first. For example should every client simply sha1 (or some other algorithm) every outgoing password?

2
please also consider posting at security.stackexchange.comTony Delroy
This has been covered quite a bit here. See Does it make security sense to hash password on client end, stackoverflow.com/questions/3715920, and stackoverflow.com/questions/6553363. From the security standpoint, a client is a client, regardless of whether its a browser or an app. Apps are marginally harder to crack than client code, but still totally insecure.Patrick M
Yes you should hash on both client and server side. There is no reason not to hash at least with a constant salt on client side especially for a mobile app as in your case. See medium.com/@harwoeck/…Leszek Szary

2 Answers

3
votes

Most websites will send the password plain-text over an encrypted connection SSL/HTTPS. Hashing the password client-side can be done, but the advantage is small and often client-side languages (JavaScrypt) are slow so you can calculate less rounds in the same time, what weakens the hash. In every case the server must calculate a hash as well to be safe.

The advantage is small, because if an attacker can do a ManInTheMiddle attack, he can also modify/remove the script (JS) which does the hashing. Only an encrypted connection with SSL/HTTPS can protect against a MITM attack, so you need SSL anyway.

In your case with an app, it looks slightly different. Because the user first has to install your software, there is no need to send a script to the client, so a MITM cannot modify this script. Moreover, the app can calculate the hash relatively fast (if it can run native code) and therefore can do enough rounds on client-side.

This is what i would do:

  1. For easiness send the password plain-text over an encrypted SSL/HTTPS connection and calculate the slow BCrypt hash server side, as you do now.
  2. Only if the load on the server grows too heavy, then you can move the calculation of the slow BCrypt hash to the client app. Still use HTTPS to send the hash, and then calculate an additional fast hash (e.g. SHA-256) on the server. This is more complex, because you have to exchange and store the salt separately.
1
votes

Another disadvantage of hashing passwords on the client is that you cannot change the hashing algorithm or iteration count without also having to update your clients.

For JavaScript clients that is not a problem, but you cannot easily guarantee that your users will be on the most recent version of your native client.

So I would stick with sending plain passwords over HTTPS.