I use a fairly standard way to log into cookies - I give the user two cookies, one with my username and the other with a randomly generated string plus a user-defined salt.
This is what happens when you log in:
$_SESSION['username']=$row[username]; $_SESSION['user_id']=$row['id']; $loginhash=generateRandomBase64String()."_".$row['salt']; $number_of_days = 14; $date_of_expiry = time() + 60 * 60 * 24 * $number_of_days ; setcookie( "userlogin", $row['username'], $date_of_expiry, "/" ) ; setcookie( "loginhash", $loginhash, $date_of_expiry, "/" ) ; $cryptedhash=crypt($loginhash); $today=date("Ymd"); mysql_query("update members set last_login='$today',loginhash='$cryptedhash' where id='$row[id]' ") or die(mysql_error());
Thus, the value of $loginhash is Pe0vFou8qe++CqhcJgFtRmoAldpuIs+d_g5oijF76 , and the encrypted version is in the database. Salt is already in the database, because it is generated for each user during registration.
I use session variables ( $_SESSION[username] ) so that users are not logged in. Then, when the user visits the site, I check two things: if $_SESSION[username] not installed, and $_COOKIE[userlogin] is there, I check that the hash is correct, so I can log in to the user system. The problem is that a hash is never correct.
if($_COOKIE['userlogin'] && !isset($_SESSION[user_id])){ $username=mysql_real_escape_string($_COOKIE['userlogin']); $loginhash=mysql_real_escape_string($_COOKIE['loginhash']); $salt=substr($loginhash,-8); $result=mysql_query("select * from members where (username='$username' || email='$username') && salt='$salt' limit 1 ") or die (mysql_error()); $row=mysql_fetch_assoc($result); $cryptedhash=$row['loginhash']; if (crypt($loginhash, $cryptedhash) == $cryptedhash){ $_SESSION['username']=$row[username]; $_SESSION['user_id']=$row['id']; } }
$_COOKIE[userlogin] is the correct value. When I check the username / salt combination in the database, I get the correct result ( echo $row[username] gives the correct value). However, the if condition if lower, which is never fulfilled. I would think that there is something strange in my PHP configuration, but I use the same encryption mechanism to store passwords and it works correctly there.
So can anyone see what is going wrong here?
PS I'm not going to start discussing the security of cookies or the many hash functions available here.