Q:

Case insensitive usernames and password salts

I have a login system
where, for example, Joe can login with the username joe without any problems. 
Currently, I am using a password encryption that uses the username as a salt.  This is creating issues for logging in.  For example,
SELECT * FROM `users` WHERE LOWER(`username`) = LOWER(`:username`)
$stmt->bindValue(':username', $_POST['user']);

This works fine.  THe trouble involves the password:
SELECT * FROM `users` WHERE LOWER(`username`) = LOWER(`:username`)
   AND `password` = :password
$stmt->bindValue(':username', $_POST['user']);
$stmt->bindValue(':password', encrypt($_POST['password'], $_POST['user'])); //encrypt(password, salt)

As you can see, the password encryption wouldn't check with the database because the user has logged in with joe instead of Joe
Is there a workaround to this, or should I use something else as a salt?  If so, what should I use as a salt?  This is my encrypt function:
function encrypt($password, $salt) {
    return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($salt), $password, MCRYPT_MODE_CBC, md5(md5($salt))));
}

A:

First off, what's the issue with using strtolower($_POST['user']) as the salt?  It looks like it would work. 
Now in general, salts should be unpredictable.  Usernames aren't really that unpredictable, so although this won't be the end of the world your users' security will be better if you replace the username with a randomly generated string of modest length (it need not be crypto-strength random, just unpredictable). 
But the biggest issue here is the use of MD5, which has been considered unsafe for some time.  Security would improve if you switched to some other hash function; SHA-1 is not a particularly bad choice (it does have an undesirable property: it's fast to calculate), but the best fit for such applications are hash functions with a variable load factor such as bcrypt.