As the OOP login tutorial is using the unsafe MD5-algorithm (despite the salt), that is potentially prone to brute-force attacks,
I would like to improve the code a bit using the crypt()-function with blowfish (most servers still don't run PHP 5.5 with the new password_hash()-function).
In the end of the day, it is probaly the best way to use a secure library, but for the sake of learning, I tried to proceed with the following:
So let's say for simplicity if we don't randomize the creation of a salt and just use a fixed value we would generate a hashed password according to the PHP-manual in the following way:
$password = 'admin'; // just an example password
$salt = '$2a$07$usesomesillystringforsalt$'; // our static salt
echo $hashed_password = crypt($password . $salt);
// This will generate a random hashed password:
// e.g. '$6$cZ87nSyraocT$29HKRGHlIu3nDTKVtlGWBAHd5/DKw9ecwoohshkRT7yWrJosNNvIExnpOIUrd2tMCzvMoioACqha6sLisnyOC1'
Every time we run this setting with the above variables, we will get a different value for the $hashed_password, which we store once in the database as the password value.
The PHP-manual then recommends to validate user input and stored password in the following way:
if (crypt($user_input, $hashed_password) == $hashed_password) { // $user_input would be $password
echo "Password verified!";
}
else
{
echo "Error!";
}
If I am running this verification test, with the above variables, I am always getting the "Error!", i.e. the comparison test fails.
So I don't really see, how to include this in the existing validate_login-function within the authentication class (m_auth.php):
class Auth
{
private $salt = '$2a$22$usesomesillystringforsalt$';
/*
Constructor
*/
function __construct() {}
/*
Functions
*/
function validate_login($user, $pass)
{
// access database
global $Database;
// create query
if ($stmt = $Database->prepare("SELECT * FROM users WHERE username = ? AND password = ?"))
{
$stmt->bind_param("ss", $user, md5($pass . $this->salt));
$stmt->execute();
$stmt->store_result();
// check for num rows
if ($stmt->num_rows > 0)
{
// success
$stmt->close();
return TRUE;
}
else
{
// failure
$stmt->close();
return FALSE;
}
}
else
{
die("ERROR: Could not prepare MySQLi statement.");
}
}
function login_status()
{
if (isset($_SESSION['loggedin']))
{
return TRUE;
}
else
{
return FALSE;
}
}
function logout()
{
session_destroy();
session_start();
}
}
I would appreciate your help on this.