Page 1 of 1

[RESOLVED]Not Giving Correct Results

Posted: Tue Oct 08, 2013 9:54 pm
by Aleeious
I made a login checking function:

Code: Select all

/**
	* checks the users login credital 
	* @param $username username to check
	* @param $password user password to check
	* @return true if login is successful otherwise false
	*/
	public function checkLogin($username, $password, $rounds = 12)
	{
		// generate the hash of the password
		$hashedpassword = $this->generateHash($password);

		// prepare the sql statement
		$statement = $this->db->prepare('SELECT password FROM ' . TABLE_USERS . ' WHERE USERNAME = ? LIMIT 1');

		// bing the variables
		$statement->bind_param('s', $username);

		// if the statement executed successfully
		if ($statement->execute())
		{
			// get the number of results
			$statement->bind_result($result);

			// fetch the results
			$statement->fetch();

			// if a result exists
			if($result)
			{
				// if the password matches
				if($hashedpassword == crypt($password, $result))
				{
					// return true
					return true;
				}
				// otherwise the password is incorrect
				else
				{
					// return false
					return false;
				}

			// otherwise return false
			return false;
			}
        }
	}
However it doesn't give the correct result. If i enter an invalid username it returns false. However wither i enter a correct password or incorrect password it returns true. The only thing i can think of is:

Code: Select all

f(crypt($password, $hashedpassword) == $hashedpassword)
which to me looks ok. Any assistance in this matter would be greatly appreciated.

Sincerely,

Aleeious

Update: tried the following code to no success

Code: Select all

if(substr($passwordhash, 0, 60) == crypt($password, "$2a$" . $rounds . substr($result, 60)))
Update 2: did some debugging and both the result and user input password hash is returning results.Still no success or idea on why it's not working.
$2a$12$dCLag3R4dIhSwDKpyGufQ.zZt8M8MFOx0V5q4ceaGVeiLA8XbjoFC
$2a$12$IjT1rMfjAc4daYcbapgteemWvgy.ADmBY1djB8JPaWsjSO2bFx0nK

Re: Not Giving Correct Results

Posted: Wed Oct 09, 2013 9:02 am
by MikuzA
Are you sure you are using the crypt()-function correctly?
The second parameter should be the salt.

Code: Select all

if($hashedpassword == crypt($password, $result))
As per above if-sentence,

$hashedpassword is the result of generateHash($password), right?
$password is $password, I guess this is in plaintext as user wrote it in the password-input box?
$result contains the query result, which again is the data of the 'password'-column.

So my assumption is, your if should be this>>

Code: Select all

if($hashedpassword == $result)
If not, can you explain what the generateHash-function does?

Hope this helps :)

Edit:

Ok, as per examples provided by php.net, I see how it can be used as you did.
The two rows on your UPDATE 2, are those the $hashedpassword and crypt($password, $result) contents?

Re: Not Giving Correct Results

Posted: Wed Oct 09, 2013 4:16 pm
by Aleeious
MikuzA wrote:Are you sure you are using the crypt()-function correctly?
The second parameter should be the salt.

Code: Select all

if($hashedpassword == crypt($password, $result))
As per above if-sentence,

$hashedpassword is the result of generateHash($password), right?
$password is $password, I guess this is in plaintext as user wrote it in the password-input box?
$result contains the query result, which again is the data of the 'password'-column.

So my assumption is, your if should be this>>

Code: Select all

if($hashedpassword == $result)
If not, can you explain what the generateHash-function does?

Hope this helps :)

Edit:

Ok, as per examples provided by php.net, I see how it can be used as you did.
The two rows on your UPDATE 2, are those the $hashedpassword and crypt($password, $result) contents?
@EDIT: Yes those are the echoed variables.

Code: Select all

// DEBUG
echo $result . "<br />"
echo $hashedpassword . "<br />"
Result:
$2a$12$dCLag3R4dIhSwDKpyGufQ.zZt8M8MFOx0V5q4ceaGVeiLA8XbjoFC
$2a$12$IjT1rMfjAc4daYcbapgteemWvgy.ADmBY1djB8JPaWsjSO2bFx0nK
Here is the code for generateHash()

Code: Select all

/**
	* Generates a hash
	* @param $password password to hash
	* @return hashed password
	*/
	public function generateHash($password, $rounds = 12)
	{
		// list the characters valid in the salt
		$validcharacters = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
		
		// repeat the loop 22 times cause the salt is 22 characters
		for($i = 0; $i < 22; $i++)
		{
			// generate the salt
			$salt .= $validcharacters[array_rand($validcharacters)];
		}

		// return the password hash using crypt
		return crypt($password, sprintf('$2a$%02d$', $rounds) . $salt);
	}
Any assistance in this matter would be greatly appreciated.

Sincerely,

Aleeious

Re: Not Giving Correct Results

Posted: Thu Oct 10, 2013 12:22 am
by Aleeious
Update:
I did a test case of the code where only the necessary code was included and the rest was striped out. I added echos where necessary to show the results of each step.

Code: Select all

<?php

	// support for crypt blowfish?
	if (CRYPT_BLOWFISH == 1)
	{
		// display support message
		echo "Crypt Blowfish Supported<br />";
	}
	// otherwise crypt blowfish isn't supported'
	else
	{
		// display nonsupport message
		echo "Crypt Blowfish Unsupported<br />";
	}

	// password 1
	$password1 = "robinandstarfiregotothemovies";

	// password 1 hash(represents user entered password)
	$password1hash = generateHash($password1);

	// password 2
	$password2 = "robinandstarfiregotothemovies";

	// password 2 hash(represents password in database)
	$password2hash = generateHash($password2);

	//rounds to run encryption
	$rounds = 12;

	// DEBUG
	echo "password1 = " . $password1 . "<br/>";
	echo "password1 length = " . strlen($password1) . "<br />";
	echo "password1hash = " . $password1hash . "<br />";
	echo "password1hash length = " . strlen($password1hash) . "<br />";
	echo "password2 = " . $password2 . "<br/>";
	echo "password2 length = " . strlen($password2) . "<br />";
	echo "password2hash = " . $password2hash . "<br />";
	echo "password2hash length = " . strlen($password2hash) . "<br />";
	echo "rounds = " . $rounds . "<br />";

	// if the password matches
	if(substr($password1hash, 0, 60) == crypt($password1, "$2a$" . $rounds . substr($password2hash, 60)))
	{
		// return true
		echo "Login Test 1 Successful<br />";
	}
	// otherwise the password is incorrect
	else
	{
		// return false
		echo "Login Test 1 Unsuccessful<br />";
	}

	// if the password matches
	if(crypt($password1, $password1hash) == $password2hash)
	{
		// return true
		echo "Login Test 2 Successful<br />";
	}
	// otherwise the password is incorrect
	else
	{
		// return false
		echo "Login Test 2 Unsuccessful<br />";
	}

	// if the password matches
	if($password1hash == $password2hash)
	{
		// return true
		echo "Login Test 3 Successful<br />";
	}
	// otherwise the password is incorrect
	else
	{
		// return false
		echo "Login Test 3 Unsuccessful<br />";
	}

	/**
	* Generates a hash
	* @param $password password to hash
	* @return hashed password
	*/
	function generateHash($password, $rounds = 12)
	{
		// list the characters valid in the salt
		$validcharacters = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));

		// repeat the loop 22 times cause the salt is 22 characters
		for($i = 0; $i < 22; $i++)
		{
			 // generate the salt
			$salt .= $validcharacters[array_rand($validcharacters)];
		}

		// return the password hash using crypt
		return crypt($password, sprintf('$2a$%02d$', $rounds) . $salt);
	}

?>
The results are below
Crypt Blowfish Supported
password1 = robinandstarfiregotothemovies
password1 length = 29
password1hash = $2a$12$R2k3gt1AafRgSRvLRGxI5.gTe0VwrjzXXgPWNT0qFgC5zK.BH1ogC
password1hash length = 60
password2 = robinandstarfiregotothemovies
password2 length = 29
password2hash = $2a$12$BKn1QNfm0vYhjHP2XUlMf.MhSl9D3cIV8.4TlOKPr3yrnK3hlXN4u
password2hash length = 60
rounds = 12
Login Test 1 Unsuccessful
Login Test 2 Unsuccessful
Login Test 3 Unsuccessful
If it helps i am hosted on one of hallsofvallhalla reseller accounts on asmallorange.com. Hopefully this will eliminate a lot of possibilities as well as help making finding the bug easier. I made a separate post to make it easier to distinguish as this is a significant departure from the original code.

Sincerely,

Aleeious

EDIT: Updated to include additional testing.

Re: Not Giving Correct Results

Posted: Thu Oct 10, 2013 6:58 am
by Winawer
You generate different salts every time so the hashes differ. That should make your login fail every time, though. Not sure why it keeps succeeding in the original post.

Re: Not Giving Correct Results

Posted: Thu Oct 10, 2013 8:18 pm
by Aleeious
Winawer wrote:You generate different salts every time so the hashes differ. That should make your login fail every time, though. Not sure why it keeps succeeding in the original post.
Thanks for the advice, i used it to get working code.

Sincerely,

Aleeious