Hashing is essentially one-way encryption. Proper hashing should not be easily reversible. So what good is hashing some data if you cannot get the original data back? Great question, and we will address it shortly. Let’s first look at an example of when to use hashing.
Say that I am building a website and I want users of the website to be able to create accounts. I will probably be storing some sort of username and password so that they can log into the system. If I am following proper development standards, I must store the password securely. The best way to do this is to encrypt it in such a way as that it cannot be decrypted even if a hacker got ahold of my database. Hashing to the rescue!
To securely store user passwords I will hash them. As I mentioned, this is intended to be a one way process. So now the question is: How can we actually use the hashed password to log someone in? Well, the nice thing about hashing is that if I am given back the original data (the password in this case) I can hash it again and compare it against the hash that I stored. If they match, I know the data matched (the password was correct).
Here is some pseudocode to explain hashing and checking a match:
// Start by hashing a password... $password = "superSecretPassword123!"; $hashed = Hash::make(password); Log.info(hashed); // $2y$10$NvEV60Zjf67Iptjbt5yXLOxjkUH1Qu6UraCLAqQ026ywAm8OK.xSu // We would store the hashed password in our database... $user = new User(); $user->email = "[email protected]"; $user->password = $hashed; $user->save(); // And then we would try to authenticate the user sometime later... $inputEmail = "[email protected]"; $inputPassword = "superSecretPassword123!"; $storedPasswordHash = User::findByEmail("[email protected]")->password; Log.info(storedPasswordHash); // $2y$10$NvEV60Zjf67Iptjbt5yXLOxjkUH1Qu6UraCLAqQ026ywAm8OK.xSu Hash::check(inputPassword, storedPasswordHash); // true // Yay, the password matched and I can authenticate the user.
One interesting thing you may find is that when you are hashing passwords properly, you will get different results each time you hash the same data. Let’s see an example:
$password = "superSecretPassword123!"; $hashed = Hash::make(password); Log.info(hashed); // $2y$10$dMbuyVAZkKvxdhrl2dR/su9faq3Ijo415afqBXA.ml4JSngyLmbRa $hashed = Hash::make(password); Log.info(hashed); // $2y$10$Ts6QXy4qXvr7teMbPj/mf.ZeCUqXrdGKzESuNOzlmzz5Ii7xoawK. $hashed = Hash::make(password); Log.info(hashed); // $2y$10$D2Xmn.HOPn54/r8DYNPgouOh7I1RF0T8rp/7JIjhhslRzbaZED8bu
Yipes, if we get different values even when hashing the data, how can we ever compare hashes? Another great question. The answer is salt, and I am not talking about the variety you use to season your food. Salt is some randomly generated data that helps the hashing algorithm arrive at a value. In order to hash the data again and get the same value, the same salt (and perhaps other factors such as number of iterations) must be used. The neat thing is that hashed data actually contains the salt that was used to produce the hash. That way, when comparing hashes, the comparison function can extract the salt from the hash to be used when re-hashing the data to compare against. Cool, right?!
Using hashing algorithms without salt for storing passwords is a bad idea. This would open up the hashed data to rainbow table attacks. Rainbow tables are a pre-computed set of hashes that can be compared against hashes you want to crack. If a match is found, the rainbow table will provide the original data. This means that an entire database of passwords could literally be decoded in seconds. It is also desireable to use hashing algorithms that are slow. This makes it more difficult to brute force attack hashes.
So remember kids, please securely hash any passwords that you will be storing in your database. At this time, some algorithms to consider are SHA-512 and bcrypt. And if you ever try to reset your password on a website and you receive an email with your original password then send them an email to let them know they should be hashing their passwords. 😄
If you'd like to comment on this article, please share on social and tag me so I can engage with you there. Thanks!