On December 11, 2010, Gawker Media was hacked. Over 1.3 million user names, passwords, and email addresses were made publicly available. In April 2011, Sony admitted that personal information, including unencrypted passwords and email addresses, for its 70 million PlayStation network users were compromised and released to the public. Malicious hackers quickly discovered that many of Gawker's and Sony's users reused their passwords for their personal email addresses and even bank accounts.
While Gawker and Sony are two of the highest profile data leaks in recent history, they are not isolated examples. Leaking user information has become a favourite method for malicious hackers and "hacktavists" to embarrass organizations. More dangerous still are the hackers who don't publicly announce and shame their victims - using leaked data to steal identities and cause trouble in secret.
A recent study by the security vendor Trusteer revealed that 73 percent of users reused their online banking password with at least one other website. With malicious hackers using more sophisticated methods to acquire user information and poor password management practices from the average user, it's important that software developers learn to securely store passwords. There are a few best practices to keep in mind.
1) Never store passwords in plain text. Your system should not need to know what the password is to properly authenticate the user. It only needs to store a cryptographic hash of the user's password. Hashes have many uses in software development, but in this context it works as a sort of one way encryption algorithm. You can easily convert a password into a hash, but it's impossible to convert the hash back into the original password without using brute-force methods. When the system authenticates a user, it should compare a hash of the user entered password with the hash stored in the database.
If we never keep a plain-text password on file, then hackers will have to brute-force or "crack" the hashed passwords before they are of any use. This is a time consuming process that involves testing potential passwords against the hash until they come up with a match.
2) Choose the right hashing algorithms for the job. MD5 is still one of the most commonly used hashing algorithms. It's designed to very quickly create a hash from large amounts of data. There are many times when a software developer will want a fast and efficient hashing algorithm like MD5 - password hashing is not one of those times. We want to use a hashing algorithm that works exceptionally slowly, even with small amounts of data (like a password).
With affordable off-the-shelf hardware - a NVIDIA GeForce 8800 Ultra for example - it's possible to compute 200 million MD5 hashes per second. This means that a hacker trying to crack a MD5 hash can test 200 million potential passwords against the hash per second.
BCrypt on the other hand, is a hashing algorithm that's designed to be glacially slow. At 1 hash per second or slower, it becomes exceptionally time consuming to crack a BCrypt hashed password.
3) Salt your hashes. The MD5 hash of the most common password - 123456 - is e10adc3949ba59abbe56e057f20f883e. This and every other common password that you can think of has already been hashed by someone and stored in a look-up table known as a "rainbow table." With a rainbow table, hackers don't even have to brute-force hashes; they just have to look them up in the table. Thankfully, there's an easy way to eliminate the effectiveness of rainbow tables: salt your hashes.
Salting is done by concatenating random data to the password before it's hashed. This random data is stored with the rest of the user's credentials so it may be used when authenticating the user's log-in attempts. With proper salting, even identical passwords will result in different hashes - rendering rainbow tables ineffective.
4) Consider using third party services for authentication. There are several cloud-based OpenId providers that can free you from ever having to touch a user's password in your own systems. You should also consider taking advantage of authentication systems built into your user's operating environment, such as Windows Active directory. As an aside, I strongly recommend that active directory users read the following Microsoft support article: http://support.microsoft.com/kb/299656.
We will take a deeper look at third party services available to us in a future entry.
In a perfect world, hackers would never obtain access to your users' information in the first place. Unfortunately we live in a world where both technical and human failures can lead to the release of sensitive information. By properly safeguarding your users' passwords, you can make it impractical for hackers to take advantage of leaked information. While the steps above won't guarantee that a hacker won't be able to crack any of the leaked passwords, it will greatly slow them down - buying yourself and your users valuable time.
As end users ourselves, we need to be mindful of the fact that our passwords exist in databases around the world, often alongside our email addresses and other personal information. No matter how complex or strong your password is, password reuse is a dangerous mistake to make.