4

Reading about hashing, salt and pepper, I can't get my head around the following scenario:

If there's a web application and you register on that site, should the password be hashed on the client or server-side? If you would consider hashing it on the client-side, you also have to generate an individual salt that then is appended to your password and that combination gets hashed and then send to the server along with the salt or you could also hash the password, send that to the server and the salt gets then appended to the hash by the server, which is then again hashed. But if an attacker is able to intercept the connection between client and server during login, he's not interested in the salt, because the client just sends the hashed (or cleartext) password to the server... And if the attacker is able to break into the database, he's still able to bruteforce the hash. So as far as my knowledge goes, salts are only useful against RainbowTable attacks(?)

What's the best practice then? Who should hash the password and where should the salt be appended?

marked as duplicate by Anders, Steffen Ullrich, Jacco, Xander, Steve Oct 25 '17 at 14:45

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2

Generally speaking salts and hashes are done server-side, not client side. The communication between server and client should be protected with encryption (TLS). As Anders mentions in a comment this may answer a lot of your questions: For an HTTPS web application, is it worthwhile to encrypt the password before POSTing it, to keep a MITM attacker from harversting it?

About salts and hashing in general: the idea behind salts and hashes often boils down to forcing the attacker to perform a brute-force algorithm. This both (a) buys the service time to secure the network and change user passwords, and (b) prevents bad actors inside the company/website from acquiring the user's password (for naughty things like trying that password on other sites).

Salts do many things. (1) protects against rainbow table attacks like you said, (2) in the case of data breach, it makes password-cracking more difficult than vanilla hash (that is, there's no way an attacker can build a database of all hashes for an algorithm; they'd have to have that database for every hash, which is not feasible); this buys the site/users time to change the algorithm and passwords, (3) prevents people working for the site to be able to easily steal a user's password, and (4) grants more architectural options for securing the authentication process.

To talk about (4) for a minute, a (very large international) client of mine had a microservice architecture, and their authentication processes worked by hashing the password with one of many salts (based on username) before sending it to the microservice which checked the actual database. This type of separation prevented the code handling the database to know both salt and password, and the microservice which knew the salt would not keep hashes (neither in-memory nor on-disk). An attacker could not use a database dump; they'd need database and software from more than one server. This increases complexity, as a stolen database gets them no closer to hashing the database; they'd also need the list of salts (from another server). No employee had access to both servers, which helped with (3).

Why hashing client-side isn't super useful: A man in the middle attack can capture whatever is transmitted between the client and the server. Hashing the password before sending does very little; the attacker doesn't have to be able to generate the hash, they'd just have to send the exact same request again to get access.

For example, let's look the following requests and parameters (I'm not using real HTTP headers for readability):

POST /auth/login
user=me@example.com
pass=mypassword

versus:

POST /auth/login
user=me@example.com
pass=89e01536ac207279409d4de1e5253e01f4a1769e696db0d6062ca9b8f56767c8

The server can't know by the hash that the real password is "mypassword", so it'll just use the hash as-is to verify the user's account. An attacker who can read that request doesn't need to know that your password is "mypassword", they just need to take the hash; that gives no protection for the account. The only thing this prevents is the attacker being able to test the password on other sites (eg, many people foolishly use the same email and password for google and their bank).

Not the answer you're looking for? Browse other questions tagged or ask your own question.