I've been working on a full stack project recently for my own amusement and would like to add authentication services to this project, but want to make sure I'm doing it the right way. And before anyone says it, yes, I know: a well-tested and trusted authentication framework is highly suggested as it's likely you won't get your homegrown authentication just right. I'm well aware of this; this project is purely for amusement as I said, and I won't be using it in a production environment (albeit I want to develop it as though it will be used in a production environment).
I believe I have a fairly adequate understanding of the basic security principles in the authentication realm such as the difference between authentication and authorization, how you should never store plaintext passwords, why you should salt your passwords, why you should always prefer to use TLS/SSL connection between the client and server, etc. My question is this:
Should passwords be:
a) hashed and salted once server-side,
b) hashed and salted once client-side and once server-side, or
c) encrypted client-side and decrypted and then hashed and salted once server-side?
Many different variations of this question have been asked before on StackExchange (such as this question which links to many other good questions/answers), but I couldn't find one question that addresses all three of these options.
I'll summarize what I've been able to glean from the various questions/answers here:
- Passwords should not only be hashed on the client-side, as this effectively allows any attackers who gain access to the hash to impersonate users by submitting the hash back to the server. It would effectively be the same as simply storing the plaintext password; the only benefit is that the attacker wouldn't be able to determine what the password actually is, meaning that they wouldn't be able to compromise the victim's accounts on other services (assuming salting is being used).
- Technically speaking, if using TLS/SSL, passwords are encrypted client-side and decrypted server-side before being hashed and salted.
- Hashing and salting on the client-side presents the unique issue that the salt would somehow need to be provided to the client beforehand.
It's my understanding that the most widely used method is to hash and salt the password server side and to rely on TLS/SSL to protect the password in transit. The main question that remains unanswered to me is what if TLS/SSL is breached? Many companies, schools, and government agencies that provide network services on site have provisioning profiles or other systems in place to allow them to decrypt network traffic on their own network. Wouldn't this mean that these institutions could potentially view the plaintext version of passwords over their networks? How do you prevent this?