Neo73 Posted March 29, 2014 Report Share Posted March 29, 2014 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. Quote Link to comment Share on other sites More sharing options...
Neo73 Posted March 29, 2014 Author Report Share Posted March 29, 2014 (edited) I found a solution, but I would appreciate your advise regarding security: Without having to import the password_compat-library via Composer, you can obviously replicate the same hashing algorithm in PHP 5.3.7 with the following code: <?php $password = 'admin'; // sample password $salt = mcrypt_create_iv(22, MCRYPT_DEV_URANDOM); $salt = base64_encode($salt); $salt = str_replace('+', '.', $salt); // Salt is stored in the authentication class echo "</br>"; echo "</br>"; echo $hashed_password = crypt($password, '$2y$10$'.$salt.'$'); // This value is stored in the database. You then safe the randomly generated $salt in the authentication class and change the validate_login-function from MD5() to crypt() as follows: ... // create query if ($stmt = $Database->prepare("SELECT * FROM users WHERE username = ? AND password = ?")) { $stmt->bind_param("ss", $user, crypt($pass, '$2y$10$'. $this->salt.'$')); ... I would appreciate your feedback. I will try as well to implement the password_compat-library. Edited March 29, 2014 by Neo73 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.