Jump to content

Oop Login Tutorial - Improving Security


Neo73

Recommended Posts

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.

Link to comment
Share on other sites

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 by Neo73
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...