How-to: Store User Passwords in a Database
Posted by Jon Lee in How-to, Web Development, tags: database, MySQL, passwords, security, tips, web developmentSo you’re creating a website that requires membership. You want users to logon using their email and password. Their credentials are stored in your database upon registration so you can check if their login is correct with a simple SELECT statement. There are several ways in which we can store this information in our database.
- Plain Text
Advantages: Users can recover password, no collision
Disadvantages: Not secure
This is the most straightforward and most insecure way of storing passwords. If a stranger ever gains access to your database, they will immediately have access to all your users’ passwords. This could potentially spell disaster if some of your users use a common password for all their Internet activity (most do in fact). On the plus side, storing passwords in plain text will allow you to send users their original passwords if they ever forget. Also, storing in plain text avoids the problem of collisions (explained later). - Hashing
Advantages: Some security
Disadvantages: No password recovery, collisions, low security.
Most sites use a hash function to store their passwords. Without going into details, what a hash does is allow a password (or any string) to be changed into a long string of hexadecimal digits. However, this process cannot be reversed to retrieve the original password (at least not easily). The most common hash these days is the md5 hash although it is far from the most secure. In PHP, the code is simply:$hashed = md5($password);
When the user registers, the original password is hashed and only the hash is stored in the database. Upon login, the entered password is hashed the same way and compared with the stored hash to validate. This however, runs into the problem of collisions. To put it briefly, it is possible for 2 different words to generate the same hash value. For example, if apple and banana had the same md5 hash value (they don’t), then if the password is actually apple, entering banana would still work! This problem is often ignored though since the chances of it happening accidentally are slim but it is a basis for a lot of md5 “cracks”.
A simple hash runs into another problem. There are reverse lookup databases where anyone can input a md5 hash and attempt to look up the original string. The database is far from complete though since it contains only the most common passwords and relatively short passwords. This is why it is important to use a long password with a combination of symbols, letters and numbers when registering for any site. Furthermore, with any hashed method of storing a password, it is not possible to remind users what the original password was, instead you would have to assign them a new password if they forget their original.
- Double hashing
Advantages: Medium security
Disadvantages: No password recovery, collisions, medium security
For added security, you can hash an already hashed string – however there are databases for double hash reverse lookups as well. I only included this as a method because I see a lot of people suggest it, but really it isn’t that much more secure than a single hash. - Salting
Advantages: High security (depending on salt)
Disadvantages: No password recovery, collisions
The best way of storing a password is to “salt” the password. What this means is to add a string of characters to a user’s password before hashing and storing it in the database. Then apply the exact same “salt” to an entered password to see if the hashes match. This salt should be something complex; salting a password with the letter “s” does not do very much good. An appropriate salt should be fairly long and consist of symbols, numbers and characters. The salt can even be dynamic! You could take the user’s birth date, subtract 4 years, add 10 days and use that as a salt. Just make sure a user’s salt always stay the same.Another method of salting is to manipulate the user’s password, i.e. reverse it before hashing, change it to all caps, take substrings, etc.
Different needs call for different methods. Sometimes you may wish to store in plain text, but if you decide to hash, follow through and make sure it really is secure – salt it!
Popularity: 4% [?]
Entries (RSS)