What every dev should know about web security: Hashing

I’m always suprised how little most backend web devs don’t know about basic security measures. These are a couple ones i feel like every web dev must know how about:

word list:
plaintext: normal human-readable text
private key: a random string used in encryption
encryption: using a private key to turn plaintext into something that can only read by others with that same key.
hashing function: A cryptographic function that takes some information and outputs a hash. You might have heard of md5, sha256, or NTLM.

Password Hashing

You should absolutely never store plaintext passwords in your database. DBs get hacked, staff has to look in the db for maintenance, people re-use their passwords everywhere.

You could encrypt the password using a private key, but anyone with the private key can still easily decrypt and gain access to the passwords.

A better way is to use a technique called hashing. See this as one-way encryption. You can hash a plaintext password and check it to the hash stored in your database, but it can never be turned back into the original password. That information in just “lost”.

UsernameSalt valueString to be hashedHashed value = SHA256 (Password + Salt value)
user1E1F53135E559C253password123E1F53135E559C25372AE25495A7981C40622D49F9A52E4F1565C90F048F59027BD9C8C8900D5C3D8
user284B03D034B409D4Epassword12384B03D034B409D4EB4B6603ABC670967E99C7E7F1389E40CD16E78AD38EB1468EC2AA1E62B8BED3A
Source: wikipedia


People then often start asking how in the world you are supposed to check if the password that the user supplied is correct. The anwser is simple: Just hash the user supplied password again and see if it matches the hash that was created during registration. As long as the input hash function, (salt), and password matches, they will always return the same output hash.

Think about it in the following way: theres multiple passwords that make for the same hash. The chance of this happening on accident or on purpose are extremely low, but still possible. thus making hashes more secure. E.g. hash("mycoolpassword") could theoretically equal hash("Thisisaverystrongpassword"). Since hashes are generally made to be quite “resource-intensive” it is not vible for an attacker to try every single password in existence, although this has been done for every combination of low-character-count passwords. These are called rainbow tables and can be downloaded online with filesizes in the terrabytes.

Salting and Peppers

A solution to these rainbow tables is called salting:

You can add a small string that is unique to every user (you might use their username, but its better to use something randomly generated) and use that in hashing: hash(password + salt). As long as this salt is unique to your application/user it won’t be as trivial to just lookup the resulting hash online.

Some applications also use something called a pepper, which is a application-wide salt that gets added to the per-user salt. This will make it even harder to crack if the attacker has both the hash and the salt, but it is generally seen as overkill.

Conclusion

Hashing is very important for any application that handles passwords. There are many more techniques that you should read about like CSRF, XSS, SQL injection. But i will leave them for what they are for now.