“I have hashed the passwords and stored them in the database, there will be no way an adversary can reverse the hashes”. All too often I have heard this coming out of application developers and infrastructure team. This is true to a certain extent, if the password was complex enough. However, many a time proper password complexity and hygiene were not abided to and due to usability issue, password complexity was not strictly enforced as well.
So what can we do to ensure that the passwords were properly secured and stored in the database? Salt and bcrypt or PBKDF2. In cryptography, a salt is a random string of data that is appended to a one-way function that hashes the data. What it primarily defend against is something known as a lookup/rainbow table attack. Find below for a simple illustration of a typical lookup/rainbow table attack.
- An adversary gains access to a database that contains non-salted passwords, hashed with SHA-1 algorithm.
- He then keys in the hash value into crackstation, an online free hash cracker. He obtains the cleartext value of the password.
CrackStation runs on a extremely large pre-computed lookup tables to attempt to crack the password hashes. The hash value obtained by the adversary was compared against the lookup table, which contains a mapping between the hash and the associated cleartext string, in this case would be “Password123”
This was only made possible because salt was not used. Imagine a random salt “Rand0mS@lt” was appended to the cleartext password before hashing, the resultant hash value of “Rand0mS@ltPassword123” would not be found in CrackStation’s lookup table.
Even with the usage of salt, it does not stop the adversary from attempting a dictionary or brute-force attack against the salted hash. Take for example MD5(Salt+Password) hash was stored in the database. Ad adversary can create his own list of MD5(Salt+Wordlists) hashes and compare them against the hash value stored in the database. This way, he would be able to retrieve the cleartext value of the password if a match occurs.
This was only achievable because MD5 is an extremely efficient hashing algorithm that calculates its hashes very quickly. We can mitigate this by using a technique known as key-stretching. bcrypt and PBKDF2 are two very slow hashing functions that can achieve this. The idea is to make the hash function slow enough such that even with custom hardware and modern GPU, dictionary and brute-force attacks are too slow to be worth the adversary’s effort in attempting so. The aim is to make sure that the hash function is slow enough to impede attacks, yet quick enough not to cause any noticeable delay for the legitimate user.
Securely salting and hashing password before storing into the database is extremely important. People tends to reuse their password on multiple sites. Given the rise of security breaches and password hashes being leaked (recent Cloudflare and Dropbox hack), this is definitely a concern that needs to be addressed.