I am connecting to a MySQL database with PHP and the CodeIgniter Framework. I want to store my passwords encrypted in the database and would like to know the best way to do this.
From a high level overview - don't encrypt, hash. And if you can, use BCrypt. Here's a long article explaining why BCrypt and why hashing.
I always md5sum passwords before I put them into the database, and then also md5sum password login attempts to check them against the db. Just for safety, I do a select query using a where clause with userID (username) AND md5summed password so that I don't get any rows back at all unless both match.
Also, mysql interanlly uses md5summing on it's passwords if you need a level of trust in this method of password obfuscation.
Use a hashing function; MD5 will do fine. Don't store the password, store the hash. Then, to log users in, hash the password they entered and compare it to the hash in the database; if the hashes match, they're legit.
Also, add a salt to the password before you hash it. This can be easy as just appending a string to the password, like your domain name or some other data that's unique to your app. This prevents hackers from using rainbow tables against your hashes.
Encrypting the passwords is a bad idea. If somebody gets your database, they're probably going to get the key you used to encrypt the passwords as well.
The real solution is to hash, salt, and then store the passwords. Jeff Atwood has an awesome post on this: http://www.codinghorror.com/blog/archives/000953.html
And here is one discussing "rainbow tables," massive tables of words with their MD5 sums: http://www.codinghorror.com/blog/archives/000949.html
This might be of some use also: What’s the difference between SHA and MD5 (in PHP)?
The best way, in that it is both easy and secure, is to use phpass. If your PHP installation does Blowfish, it uses bcrypt; if it doesn't, it uses multiple passes of md5. Either way, it's more secure than straight md5 or sha1.
$hasher = new PasswordHash(8, false);
// Before storing a password
$hash = $hasher->HashPassword($password);
// To check a password against a hash
if ($hasher->CheckPassword($password, $hash))
// $password and $hash match
hmm, I hash, more than once based on whatever math springs to mind at the time of writing the storing and validation of passwords
From here on I'll probably go with OpenID as much as possible wherever I have an actual choice tho, so i don't have to do any password storage at all. That way I can leave passwords up to the experts, and the users already trusted party.
I agree with hashing and salting. I disagree with picking a site-wide hash. Use a different salt for each user to prevent dictionary attacks against all your passwords at once.