First on the issue of password storage... Since you seem to be using PHP (from your question history)... Salted sha1()
hashes just won't cut it in a world where renting a few AWS instances to compute fast rainbow tables... sha1()
is too fast.
Instead of trying your hand at do-it-yourself cryptology, why not trust libraries made by actual experts in the field? Use the Portable PHP password hashing framework.
PHPass actually uses bcrypt, which is an algorithm designed to prevent rainbow table, dictionary and brute force attacks. You can initialize it with a number of rounds: the higher the rounds, the longer it takes to compute the hash. That way, you can create stronger hashes if processing power increases.
Using it is simple:
require('PasswordHash.php');
$phpass = new PasswordHash(12, false); // Initiate for 12 rounds, using bcrypt
// Hash a password
$hash = $phpass->HashPassword('my secret password');
// Compare an hash to a given password
$formSupplied = 'hello world';
$isRight = $phpass->CheckPassword($formSupplied, $hash);
if($isRight) echo "Good";
else echo "Wrong";
Now on the subject of usernames... Store them using a _bin
collation (ie.: utf8_bin
). This will force MySQL to binary compare when during a WHERE
and effectively makes your usernames case-sensitive.
HOWEVER, since this is UTF-8, it is going to be important to normalize the username before inserting and querying your data. Different operating systems represent accented characters in different ways. PHP has the intl
extension which has a facility for UTF-8 normalization. The following should do:
$_POST['username'] = Normalizer::normalize($_POST['username']);