A recent post on passwords
I got a little off topic and covered a lot of this. A tidbit:
Once you are happy with the password they have picked encrypt it with PHP first, then store. The following password encryption function is not my idea either, but solves a number of problems. Encrypting within PHP prevents people on a shared server from intercepting your unencrypted passwords. Adding something per user that won't change (I use email as this is the username for my sites) and add a hash (SALT is a short constant string I change per site) increases resistance to attacks. Because the SALT is located within the password, and the password can be any length, it becomes almost impossible to attack this with a rainbow table. Alternately it also means that people can't change their email and you can't change the SALT without invalidating everyone's password though.
function password_crypt($email,$toHash) {
$password = str_split($toHash,(strlen($toHash)/2)+1);
return hash('sha256', $email.$password[0].SALT.$password[1]);
}
So on first input of the user password, in pseudo code:
define(SALT,'blah');
$hashed_password = password_crypt($email,$password);
INSERT INTO users (email,hashed_password) VALUES ($email,$hashed_password);
Then to check a subsequent login in pseudo code:
define(SALT,'blah');
$user_hashed_password = password_crypt($_POST['username'],$_POST['password']);
SELECT email FROM users WHERE email = ? AND hashed_password = $user_hashed_password LIMIT 1
If you get a row back, valid login.