如果我们使用salt技术,如何根据输入的密码检查Mysql数据库中的密码


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

我的网站上有登录和注册系统,我想在将用户密码存储在MySQL数据库中之前,使用一种强大的方法加密用户密码。我用这个代码来加密密码:

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 

当用户尝试登录时,我会用这个来检查密码:

$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';
  }

我使用crypt是因为我的PHP版本不支持password_verify

我的问题是:我仍然一直得到not correct

我想给每个用户一个不同的salt' and I want to check it by密码`

我必须更改此代码中的任何内容吗?为什么它一直给not correct

双引号字符串中的美元符号作为变量进行插值,因此示例中$database_password_hash的实际值为'$2a$07.Viq5UnNReGMy'。请改用单引号。

这对我有效:

$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';
}

您知道password_hash()函数存在兼容包吗?也许你可以直接使用这个函数,稍后当你切换到一个新的PHP版本时,你可以删除这个库的include,代码仍然可以工作。

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

此函数之所以有效,是因为它在生成的哈希值中包含salt。函数password_verify()可以从中提取它。实际上是crypt()函数完成的,所以您的代码也将包含salt。

首先,使用SALT创建哈希时,需要返回哈希和创建哈希时使用的SALT。

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

现在,当你验证登录时使用了正确的密码时,你会:-

// 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';
}

Crypt总是让我感到困惑。这就是为什么我只使用基本的Hash函数。

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');
}