Okay, so all of the code below is not my own. I’ve been following a tutorial on the internet, but when I try and run it, no password seems to be matching. I believe there may be an error with salting the password as what is in the database is nowhere near the 64 characters that is described in the login.php script. I have no idea. Code is below:
register.php
// Create a 256 bit (64 characters) long random salt
// Let's add 'something random' and the username
// to the salt as well for added security
$salt = hash('sha256', uniqid(mt_rand(), true) . 'something random' . strtolower($username));
// Prefix the password with the salt
$hash = $salt . $password;
// Hash the salted password a bunch of times
for ( $i = 0; $i < 100000; $i ++ )
{
$hash = hash('sha256', $hash);
}
// Prefix the hash with the salt so we can find it back later
$hash = $salt . $hash;
// carry on with registration code...
login.php
$email = $_POST['email'];
$password = $_POST['password'];
$con = mysql_connect("localhost", "redacted", "redacted", "redacted");
$sql = '
SELECT
`password`
FROM `users`
WHERE `email` = "' . mysql_real_escape_string($email) . '"
LIMIT 1
;';
$r = mysql_fetch_assoc(mysql_query($sql));
// The first 64 characters of the hash is the salt
$salt = substr($r['password'], 0, 64);
$hash = $salt . $password;
// Hash the password as we did before
for ( $i = 0; $i < 100000; $i ++ )
{
$hash = hash('sha256', $hash);
}
$hash = $salt . $hash;
if ( $hash == $r['password'] )
{
session_start();
header('Location: /quiz/index.php');
}
if( $hash != $r['password'] ){
session_start();
header('Location: /?error=4');
}
// end login script
A common error is when database fields are not long enough to store all the characters. The password then will never equal what the user entered.
For this kind of functionality, always write unit tests that check if the function (still) works as expected. One day someone will modify the database, change the hash algorithm, modify the salt… and noone will be able to log in.