문제

As part of learning php, I wanted to try a register and login page, however, the site I'm following for how to store a password uses MySQLI and I'm not using that:

Hashing the password

$password1 = 'hello123';
// A higher "cost" is more secure but consumes more processing power
$cost = 10;

// Create a random salt
$salt = strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.');

// Prefix information about the hash so PHP knows how to verify it later.
// "$2a$" Means we're using the Blowfish algorithm. The following two digits are the cost parameter.
$salt = sprintf("$2a$%02d$", $cost) . $salt;

// Value:
// $2a$10$eImiTXuWVxfM37uY4JANjQ==

// Hash the password with the salt
$hash = crypt($password1, $salt);

I'm stuck on retrieving the password however, here's the site's code for it:

$username = 'Admin';
$password = 'gf45_gdf#4hg';

$sth = $dbh->prepare('
  SELECT
    hash
  FROM users
  WHERE
    username = :username
  LIMIT 1
  ');

$sth->bindParam(':username', $username);

$sth->execute();

$user = $sth->fetch(PDO::FETCH_OBJ);

// Hashing the password with its hash as the salt returns the same hash
if ( crypt($password, $user->hash) === $user->hash ) {
  // Ok!
}

From what I can see, he grabs the hash value of the password for the user in the DB and compares the password that was passed using the hash and check with the one in the DB.

I've been trying this but the result hash is never the same as the original one:

$pwdtocheck = 'hello123';

// no call do DB yet, doing this on the same page after hashing, the $hash is the same as above
$pwdhash = crypt($pwdtocheck, $hash);

// if I echo $pwdhash it's never exactly the same as the $hash.
if ( $pwdhash === $hash) {
  echo "same pwd";
}
도움이 되었습니까?

해결책 2

EDIT:

I see now that you are using a salt when you compare the passwords. In your line:

$pwdhash = crypt($pwdtocheck, $hash);

the $hash variable has the salt prepended to it because crypt() will automatically do that for you. crypt() will extract the salt from the $hash because it knows the expected length of the salt based on the algorithm used. See the documentation.

I'll keep my original answer below for context and for those looking for a similar answer.

END EDIT

The password is not the same for you because you are using a salt when you originally hash the password to put in your database, but you are not salting the password later when you check against the database.

You should use the same salt string when you save the password as when you check the user's password on login. Usually, you will randomly generate the salt string for each password (as you are doing) and then save the salt string to the database along with the hashed password (either in the same column or its own column) so that you can use the same salt to check the user's password on login.

See https://crackstation.net/hashing-security.htm#salt for reference.

다른 팁

I cannot see the actual problem in your code, maybe your database field is smaller than 60 characters, or you are comparing different passwords. In every case there is an easier and safer way to hash passwords, just use the new functions password_hash() and password_verify(). There exists also a compatibility pack for earlier PHP versions.

// 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);

I can't access the article you're referencing but I imagine:

You need to check using the salt as the salt and not the hash.

crypt($pwdtocheck, $user->salt) == $user->hash

should work

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top