Search code examples
securityhashpasswordsclientpassword-hash

Client side password hash versus plain text


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?


Solution

  • 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.