A modern approach to password management
In light of Cyber Security Month, I wanted to write something that has been bothering me for a while. Most companies way of handling memorized secrets, better known as passwords.
For most projects, it is often easier to use third-party authentication. A lot of popular sites offer this service (Facebook, Twitter, Google, Github, ….). More often than not your users will already have an account on one or more of these platforms.
But, sometimes you will still want to manage passwords yourself and there are some things to consider.
The length of a password is the most impactful on the security. If you only consider one thing while choosing a password this should be it.
There is a common practice amongst hackers called brute-forcing. When they attack a site in this way they will try every possible combination of characters to gain entry. And password length provides the biggest hurdle here. For example, if your password is "Appel" it will only take around 10 milliseconds to guess it. If your password is "Pineapple" (still a terrible password) it will take around 19 hours. That is already a decent increase, but if you choose "ILoveApplesInMyFruitSalad". The time to brute force your password goes up to 6 septillion years. The official recommendation of OWASP is to have at least 8 characters in your password. You should enforce this in your application.
You can calculate the time it takes to brute force a password on howsecureismypassword.net.(do not enter your actual password)
Besides length, there should not be any more rules for passwords. This is something most companies get wrong. When you force your users to use: 5 special characters, a combination of lower- and uppercase letters, 4 numbers, and the name of their favorite pokemon. Chances are they will forget the password. Or the only way they will remember it is by scribbling it down on a post-it that hangs on their screen.
The same principle applies when it comes to rotation. If you require your users to change their password every couple of months and it has to be different every time they will most likely use an increment (Password1, Password2, Password3, ???) or write it down on a post-it.
Besides length, the strength of a password is also dependent on how simple it is to guess. Did the password appear in a leak? Is it a common password? Does it appear in a rainbow table? These cases are more difficult to secure against. But there are some extra checks you could perform. For example, you can test new or changed passwords against the 10000 worst passwords. Or whenever there is a large leak run a test on your passwords against the leaked data.
You can not store your passwords the same way you store other data. Should you happen to be unfortunate enough to have a breach and your data is leaked. All passwords should be illegible to readers. The best way to achieve this is with hashing.
A hash is a one-way mathematical transformation of a piece of data to a fixed-sized bit string. In contrast to encryption, hashing does not have a way to unhash the result.
For passwords, the algorithm should be complex enough that it takes a bit of time. That way when someone tries to match a password with the resulting hash they get delayed at each attempt.
The use of a modern and proven safe hash algorithm is important. MD5 and SHA-1 are unsafe. At the time of writing SHA-3, SHA-256 or bcrypt are better alternatives. But this might change over time, so keeping yourself up-to-date is the answer.
Although hashing alone is not enough anymore. Hash functions are deterministic. The same input will always result in the same output. This means when hackers see that several users have the same hash, they know those users also use the same password. Or they could use a Rainbow Table Attack as well. With this method, they use a large database of precomputed hashes to find common passwords in a short amount of time. You mitigate these vulnerabilities by adding a salt to the hash.
When adding a salt to your hash you make it seem non-deterministic. You generate a unique string each time a user creates or updates a password. Then prepend or append the salt to the password before running it through your hashing algorithm. If you do this, two password hashes will never look the same.
OWASP suggests using a secure random for your salt generation with a size of 32-byte or 64-byte. The larger the better, because of the increased complexity. When storing your salt there is no need to further encrypt or obscure it. You can store the salt next to the password hash in cleartext. But, do not make the salt easily accessible to the public. So no usernames or emails.
Managing passwords well is not an easy task. But it is an integral part of your security setup. And often done wrong. Make sure your company does this right and keep yourself informed. Some great resources about this topic can be found on owasp.org and nist.gov.
Stay secure! 👋