Basel Shbeb
Basel Shbeb

Reputation: 11

How to check the password in Mysql Database against the entered one if we are using salt technique?

I have login and register system in my website I want to use a powerful way to encrypt users passwords before storing them in my MySQL database . I use this code to do encrypt the passwords :

function better_crypt($input, $rounds = 7)
  {
    $salt = "";
    $salt_chars = array_merge(range('A','Z'), range('a','z'), range(0,9));
    for($i=0; $i < 22; $i++) {
      $salt .= $salt_chars[array_rand($salt_chars)];
    }
    return crypt($input, sprintf('$2a$%02d$', $rounds) . $salt);
  }

  $user_password = "123456";
  $password_hash = better_crypt($user_password);
  //$password_hash = "$2a$07$t8Omz2TZhz5u0AI3l8uB4uQxzqYZCoqEsQmRo1gr.Viq5UnNReGMy";=> store in database 

And when a user try to login I use this to check the password :

$password_entered = "123456";

  $database_password_hash = "$2a$07$t8Omz2TZhz5u0AI3l8uB4uQxzqYZCoqEsQmRo1gr.Viq5UnNReGMy";// I get this from database depending on the username

  if(crypt($password_entered, $database_password_hash) == $database_password_hash) 
  {
    echo 'password is correct';
  }
  else
  {
    echo 'not correct';
  }

I use crypt because my PHP version does not support password_verify .

My problem is : I still get not correct all the time .

I want to give each user a different salt' and I want to check it bycrypt`

Do I have to change anything in this code ?why does it give not correct all the time?

Upvotes: 0

Views: 1348

Answers (4)

chozilla
chozilla

Reputation: 159

Crypt always confuses me. Thats why I just use basic Hash functions.

function verifyPassword($input, $dbHashOfPassword, $dbSavedSaltForThisUser)
{
    return $dbHashOfPassword === $this->hashPassword($input, $dbSavedSaltForThisUser);
}

function hashPassword($password, $salt)
{
    return hash('SHA512', $password.$salt);
}

function createSalt($username, $userid, $systemTime, $anything)
{
    //Do stuff to create a Unique Salt for your user.
    //This has to be stored in the database as well but 
    //will have the impact that every attacked userdata will 
    //need there own rainbow table created.
    return hash('MD5', 'T-'.$systemTime.'-U-'.$username.'-A-'.$anything.'-ID-'.$userid.'-E');
}

Upvotes: 0

RiggsFolly
RiggsFolly

Reputation: 94682

First when you create your hash, with a SALT, you need to return both the hash and the salt that was used in creating the hash.

function better_crypt($input, $rounds = 7)
{
    $salt = '';
    $salt_chars = array_merge(range('A','Z'), range('a','z'), range(0,9));
    for($i=0; $i < 22; $i++) {
      $salt .= $salt_chars[array_rand($salt_chars)];
    }
    $salt = sprintf('$2a$%02d$', $rounds) . $salt);
    $hash = crypt($input, $salt);
    return( array('hash' => $hash, 'salt' => $salt);
}


$user_password = '123456';
$better_result = better_crypt($user_password);
// Store the $better_result['hash'] 
// AND 
// $better_result['salt'] 
// to the users table in the database

Now when you are validating that the correct password was used at login you do :-

// Get from the database the users hashed password and the salt used to create the hash.

if( crypt($password_entered, $salt_from_users_row) == $database_password_hash) 
{
    echo 'password is correct';
} else {
    echo 'not correct';
}

Upvotes: 0

Roel Harbers
Roel Harbers

Reputation: 1074

The dollar signs in your double-quoted string are interpolated as variables, so the actual value of $database_password_hash in your example is '$2a$07.Viq5UnNReGMy'. Use single-quotes instead.

This works for me:

$password_entered = '123456';
$database_password_hash = '$2a$07$t8Omz2TZhz5u0AI3l8uB4uQxzqYZCoqEsQmRo1gr.Viq5UnNReGMy';// I get this from database depending on the username
if(crypt($password_entered, $database_password_hash) === $database_password_hash) {
  echo 'password is correct';
} else {
  echo 'not correct';
}

Upvotes: 1

martinstoeckli
martinstoeckli

Reputation: 24151

You are aware that there exists a compatibility pack for the password_hash() function? Probably you can use this function directly then, later when you switch to a new PHP version you can just remove the include to this library and the code will still work.

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

This function works because it includes the salt in the resulting hash-value. The function password_verify() can extract it from there. Actually it is the crypt() function doing it, so your code will include the salt as well.

Upvotes: 1

Related Questions