History can truly be one of the best guides for highlighting a path that should never be taken, or conversely, highlighting another path that should always be taken. If you have been following the headlines, you are aware that one of the biggest companies on this Earth, Sony, has been under constant attack by malicious hackers. Despite what the motivations are for such an assault, there is an enormous collateral damage in the swindling of innocent end user data. This breach included email addresses, home addresses, possible financial information, and even more important: user passwords.
As a programmer, we all know that the goal of receiving and storing a user’s personal and private information is to guard that information using all means necessary. We would love it if users provided unique passwords that included no words in a dictionary, had mixed casing, and made use of every keyboard symbol available. Truth is, that many people value an easy to remember password rather than the significance of a long and jumbled one. With hundreds of logins to remember, it is just plain easy for users to reuse passwords across multiple services. From the development side, we must come up with a worst case scenario and try to protect that sample as best we can. Password hashing is an excellent step in the right direction but it is certainly not the only step to be taken.
Password hashing is a way to scramble up a plain text password, almost creating a scrambled digital fingerprint of the original data value. With this method, the database would then store the hashed password instead of the plain text version. Now, when the user wants to login and provides their password, this same hashing function is called and the hashed value is then validated against the stored hashed value in the database. As you can see, this has already provided a buffer zone of security for your clients since their actual password is not being stored in a potential treasure trove for malicious activities. Should we stop there? Are there any other things we should be contemplating?
We have already established that password hashing will mutate a password into something unrecognizable even to the person that entered it. We can’t feel completely satisfied yet because unfortunately, there are nefarious ways to reverse engineer these cryptographic hashes through tables called “Rainbow Tables.” These tables hold pre-computed hash values on all varieties of words (i.e. any words contained in a dictionary). These tables can be enormous, but through a lot of data crunching, it is feasible for someone with malicious intent and access to the hashed passwords to try to find a match and subsequently decode the original password. With computer hardware reaching new limits every day, this is a very real danger considering the level of processing power available. Just as an example, if you have a user that enters “password” as their password, reverse engineering the hashed value of “password” through a rainbow table would be fairly easy. Fortunately, we can help protect our users by implementing “cryptographic salt” on top of our hashing function.
The longer a given password is and the least resemblance to normal diction it has, the higher the chances that they won’t be contained in rainbow tables. By adding “salt” to the mix, we are essentially adding a random set of characters to the password before hashing it, thus taking care of both of the latter concerns. One example of adding salt would be generating a set of characters on the fly programmatically, appending this to the original password value, hashing that result, and then storing that computed salt in another location to be used in validation at a later date. Adding salt to our easy–to-reverse-engineer “password” will now add a level of complexity that will beat “dictionary attacks” and leave no choice but for a “brute force” attack of trying every combination of letter/number/symbol possible. Of course right away, you might want to get creative in how you store that salt or someone that battles their way into your database might be able to establish the relationship in the data.
As stated at the beginning of this article, let history guide us. We know as developers that it is our moral responsibility to protect our users as much as possible. It also makes a lot of business sense that we would want to maintain our data integrity. It is a very grey area trying to find that fine line between convenience and security. In Sony’s misfortunes, it should really sound the alarm for all web developers to reevaluate their own protocols in place. This is a process that will always be changing as technology changes every day, and that means that we need to constantly review and update as necessary. There are many “seasonings” we can add to the meal such as minimum password lengths, requiring numbers and letters, allowing random symbols, and adding a login attempt counter. One ingredient, however, that is essential in our preparation now is the salt that will protect all users in case of an unexpected security breach.