使用salt / password / hash进行密码验证时出现问题

时间:2014-04-22 16:39:23

标签: php hash

我有一个函数可以通过生成salt,将其附加到密码并对组合进行散列来创建新用户。我还有另一个用户登录验证功能,它使用用户输入的密码并将其添加到用户的唯一盐,哈希值,并与数据库中的加密密码进行比较(请参阅整个代码中的注释)。

我已经回显了userValidate()函数中的所有重要变量,但是我永远无法获得哈希+用户密码来匹配数据库中的加密密码。谁能告诉我我做错了什么?

创建用户功能:

function createNewUser($firstName, $lastName, $email, $password, $address, $city, $state) {

    $conn = connectPDO();

    // Create a salt
    $salt = mcrypt_create_iv(64, MCRYPT_DEV_URANDOM);

    // Add salt to password
    $salted_password = $salt.$password;

    // Hash salt/password combination, to be added to "password" column of database
    $encrypted_password = hash('sha256', $salted_password);

    $datetime = date("Y-m-d H:i:s");

    $stmt = $conn->prepare("INSERT INTO users (`first-name`, `last-name`, `email-address`, 
                             `password`, `salt`, `address`, 
                             `city`, `state`, 
                             `registered-timedate`) VALUES (
                                :field1, :field2, :field3, :field4, :field5, :field6, :field7, :field8, '$datetime')");

    return ($stmt->execute(array('field1' => $firstName, 
                         'field2' => $lastName, 
                         'field3' => $email, 
                         'field4' => $encrypted_password, 
                         'field5' => $salt, 
                         'field6' => $address, 
                         'field7' => $city, 
                         'field8' => $state)));
}

验证用户的登录信息:

function userValidate($email, $user_password) {
    $conn = connectPDO();
    $sql = "SELECT `salt`,`password` FROM users where `email-address`='$email'";
    $q = $conn->query($sql);
    $row = $q->fetch();

// Get the user's unique password salt
$salt = $row['salt'];

// Find the hashed salt/password combination
$database_password = $row['password'];

// Add salt to user's entered password and encrypt
$salted_password = $salt.$user_password;
$encrypted_password = hash('sha256', $salted_password);


// Compare the user password/salt hash to one stored in database
if($encrypted_password == $database_password) {
    return true;
} else {
    return false;
}
}

编辑:

我已经在注册页面上回复了我的vars,我得到了许多特殊字符的盐,例如“J~×/ q,ó¸5áczçvÁ!-Î/åÿâÑ^:h1Z¬MÃF¤ º`“U

1 个答案:

答案 0 :(得分:1)

我怀疑你遇到了这两个问题之一:

  1. 散列密码的数据库字段太小,该字段必须能够存储64个字符。
  2. 您的salt的编码存在问题,请记住,使用mcrypt_create_iv()生成的salt是二进制字符串,可以包含任何字符(甚至是\ 0字符)。
  3. 即使您可以解决此问题,您也有一个不安全的方案来存储密码(SHA256对于散列密码来说太快了)。看看PHP函数password_hash(),它将生成一个BCrypt哈希并负责生成安全盐。盐将成为生成的62个字符串的一部分,因此无需单独存储盐。对于较旧的PHP版本,还存在compatibility pack

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