While writing some new code today, I re-visited the sensitive topic of 'passwords'.
What is the worst way to store your users' passwords?
Plain-text should never be an option to store your users' passwords. And neither should you just use any simple encryption. Passwords need to be hashed.
Encryption v/s Hashing
Encryption is a two way function. It creates a set of variable-length unreadable characters, that can be decrypted, if you have the right key. This cannot be used to store passwords, because if an attacker gets access to the users database and the key, they can retrieve the plain-text passwords. This is unsafe because a lot of users repeat their passwords on different online services.
Hashing is a one way function. It creates a fixed-length fingerprint of a password of any length; and this fingerprint cannot be reversed. If the password differs even by a single character, the fingerprint is completely different. This is definitely the way to go for safely storing passwords, because even if your users database is breached, your users' passwords cannot be recovered (easily).
So, what is the best way to store your users' passwords?
Secure Hashing; add salt.
While hashed passwords, technically, cannot be reversed, the hashed values can be compared against dictionaries and rainbow tables, in brute-force attacks. Hence, you must add salt before hashing the stored passwords.
Salt is a string that is added to the password. The salt needs to be unique for each hashed and stored password. Unique, well-salted passwords will not exist in dictionaries or rainbow tables and hence cannot be reversed.
Further, using slow-hashing functions slow down an attacker from retrieving your users' passwords. This can be achieved by using functions like PBKDF2 or Bcrypt. These functions iterate over the password + salt multiple times, thus making cracking more difficult. This is known as key stretching.
Hashing protects your users' passwords from being reversed into plain-text, so that the attacker cannot use these passwords on other websites and services.
However, this does not prevent an attacker from gaining access into your user's individual account, especially if they have a poor password or if you have poor login protocols. Some basic protocols you can follow to secure your users are:
- Use HTTPS / SSL on any page that a user enters their password, so that the data between the user's browse and your server is encrypted. This ensures that no sniffer on the LAN or ISP can read the password.
- Lock a user after multiple failed login attempts.
- Enforce strong passwords of at least 12 characters, that include alphabets, at least one digit and a special character.
If this post has helped you learn something new today, do share it with your friends, colleagues and grandparents.
If you have experience in creating secure login systems, I'd like to know which hashing algorithm you use or recommend. You can comment below or contact me directly.