Hashed Passwords, Rainbow Tables, and Salted Hashes Simply Explained

Storing passwords correctly and securely in a database can avoid security nightmares, yet many organizations don't follow best practices and pay the price.

Roman Tetelbaum
Geek Culture
4 min readJan 4, 2021

--

Storing passwords in plaintext in an organization’s database is a terrible idea. Database breaches are all too common, and if your organization’s database is breached, the attacker now has access to some if not all user passwords. Plaintext simply means that the data is stored in clear, human-readable format, such as “MyPassword1992”. Many organizations to this day still store your password in plaintext either intentionally or as a result of an oversight for a part or all of their user base. As recently as 2019, even companies like Google and Facebook have exposed user credentials due to poor security practices. You might think that companies that play such an integral role in the development of the modern web would take the security of their own user base more seriously, but this simply isn’t true. From one of Facebook’s own recent breach announcements:

“We estimate that we will notify hundreds of millions of Facebook Lite users, tens of millions of other Facebook users, and tens of thousands of Instagram users.”

These numbers are staggering. Here is a snippet from a vulnerability discovered within Google and announced in 2019:

We made an error when implementing this functionality back in 2005: The admin console stored a copy of the unhashed password. This practice did not live up to our standards.

Pay particular attention to the date. This vulnerability was not discovered by Google for 14 years. Although Google claims there is no evidence that the passwords were accessed by unauthorized parties, there is no way to know for sure. 14 years is an eternity in the life of the internet.

Hashing a password simply means putting the plaintext through a hashing function algorithm that transforms the plaintext into what appears to be gibberish, taking the aforementioned “MyPassword1992” and transforming it into “A0E01F00D4D7A17EA9D0240795E257BE25533489”. Unlike encryption, a hash function is a one-way operation, meaning it cannot be “unhashed” in the way that something that is encrypted can be decrypted with the correct key. If given the above hashed password, there is no way to derive “MyPassword1992” back from the hashed version. The problem with hashing, however, is that the same input will always result in the exact same output when put through the same hash function algorithm. Attackers can then use something called a rainbow table which matches common passwords with their corresponding hashes. This saves the attacker time and computing resources since they no longer have to wait to run a list of commonly used passwords through hashing functions before attempting to breach an account. Storing a hashed password in an organization’s database versus plaintext is a step in the right direction. This way if there is a breach, the attacker has to do some work to figure out if any of the hashes correspond to commonly used passwords. If a match is found in the table, it’s as good as if the password was stored in plaintext. Rainbow tables can contain millions of passwords using combinations of common words, digits, special characters, and phrases.

The combination of the all too common poor user habits of weak and predictable passwords as well as organizations that store the passwords in hashes (or, God help us, in plaintext) creates a vulnerability with the existence of rainbow tables. The solution is to use something called a salt, which adds a fixed length random string of characters to either the beginning or the end of the password before running it through the hash function. This effectively destroys the utility of the rainbow table by making something like “MyPassword1992” look like “MyPassword1992h#6gHgd5!” before it even hits the hashing algorithm, making the resulting hash entirely unpredictable even if the user password is. If the organization stores this salted hash in its database instead of your plaintext password, when you attempt to log in, it will take your password, salt and hash it, and compare that value to the stored salted, hashed password, instead of comparing plaintext to plaintext. This way if the database is compromised, there is no way to match a hash against a rainbow table of known passwords, and the stolen data is useless.

It’s important to understand that it’s still crucial to use strong passwords despite this added security feature that some organizations have implemented. If someone guesses your password, or uses a brute force attack where they guess using common passwords, they will still be able to compromise your account. Hashing and salting a password protects your password while it’s stored on the server of the organization, it does not protect your password from being guessed, discovered on a Post-It note on your desk, or in a plaintext file on your computer. Best practices include using a secure password manager like Bitwarden (which itself should be protected using a single, long, and complex password that you can remember, but this is the only password you will have to remember), 2FA (two-factor authentication) using an app like Authy if the organization has that feature (which any organization worth its salt, if you’ll pardon the expression, should already be using), and salted hash password storage at the database level. As a user you should have absolute control of the first in this list of best practices, so avail yourself of the use of a good password manager and secure it with solid password you can remember. 2FA is becoming more popular so check if your accounts have that option and enable it if so. Salted hashes? Let’s hope that the organizations that store your credentials have wised up!

References and Additional Resources:

--

--