【问题标题】:Cannot compare BCRYPT passwords无法比较 BCRYPT 密码
【发布时间】:2012-10-31 05:00:02
【问题描述】:

我正在关注本网站http://www.gregboggs.com/php-blowfish-random-salted-passwords/ 中的指南,但由于某种原因,在检查密码是否相同时它失败了。

html 很简单,2 种形式,一种用于创建帐户,一种用于检查。代码可以看这里http://jsfiddle.net/Xf2Tc/

作为输出我得到: salt = 数据库中的盐 数据库密码:$2a$05$BcTDz3GVPJrLH3YRPF9FZ.uRBssr0ncQ4exG4/EtmnJ7Fz2CkoVha 但是重新加密的密码总是非常小。 BcPgSBqZz80dw

我一定是用错了盐什么的。

如果有人可以编辑得更有条理,我将不胜感激。

<?php 
defined( '_JEXEC' ) or die( 'Restricted access' );
    $hostname="exampleHost";
    $database="exampleDB";
    $username="exampleUsername";
    $password="examplePassword";
    if(isset($_POST['Upassword'])&&isset($_POST['account'])&&!empty($_POST['Upassword'])&&!empty($_POST['account']))    {
        try {
            $pdo = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            $Upassword = mysql_real_escape_string($_POST['Upassword']);
            $account = mysql_real_escape_string($_POST['account']);

            //This string tells crypt to use blowfish for 5 rounds.
            $Blowfish_Pre = '$2a$05$';
            $Blowfish_End = '$';

            $Allowed_Chars ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
        $Chars_Len = 63;

            // 18 would be secure as well.
            $Salt_Length = 21;

            $mysql_date = date( 'Y-m-d' );
            $salt = "";

            for($i=0; $i<$Salt_Length; $i++)
            {
                $salt .= $Allowed_Chars[mt_rand(0,$Chars_Len)];
            }
            $bcrypt_salt = $Blowfish_Pre . $salt . $Blowfish_End;

            $hashed_password = crypt($Upassword, $bcrypt_salt);
            $stmt = $pdo->prepare("INSERT INTO users (reg_date, account, salt, password) VALUES (:mysql_date, :account, :salt, :hashed_password)");
            $stmt->bindParam(':mysql_date', $mysql_date, PDO::PARAM_STR);
            $stmt->bindParam(':salt', $salt, PDO::PARAM_STR);
            $stmt->bindParam(':account', $_POST['account'], PDO::PARAM_STR);
            $stmt->bindParam(':hashed_password', $hashed_password, PDO::PARAM_STR);
            $stmt->execute();
        } catch(PDOException $e) {
            //file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
            echo 'ERROR: ' . $e->getMessage();
        }
    }
            /*
                * to test for correct encryption
                *
            */
                  if(isset($_POST['Upassword2'])&&isset($_POST['account2'])&&!empty($_POST['Upassword2'])&&!empty($_POST['account2']))  {
    try {
        $pdo = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
        $stmt = $pdo->prepare("SELECT salt, password FROM users WHERE account=:account");
        $stmt->bindParam(':account', $_POST['account2'], PDO::PARAM_STR);
        $stmt->execute();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        $Upassword2 = mysql_real_escape_string($_POST['Upassword2']);
        echo $row['salt'];
        $bcrypt_salt = $Blowfish_Pre . $row['salt'] . $Blowfish_End;
        $hashed_password = crypt($Upassword2, $bcrypt_salt);

        echo "PassDB: " .  $row['password'];
        echo '-------------------------------------------';
        echo "result: " .  $hashed_password;
            echo '-------------------------------------------';
        if ($hashed_password == $row['password']) {
          echo 'Password verified!';
          }
          echo 'i am here';

    } catch(PDOException $e) {
    //file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
    echo 'ERROR: ' . $e->getMessage();
    }
}
?>

【问题讨论】:

  • 使用password_compat它简化了密码散列的过程BCRYPT
  • 我不明白您问题的“重新加密的密码”位。这甚至看起来与生成它的算法完全不同。
  • 您在$_POST['Upassword']$_POST['account'] 上使用mysql_real_escape_string 是否有原因?由于您使用的是PDO,它会自动转义您的数据,并且很可能您的$Upassword$account 现在不是您认为的那样,因为您需要打开的mysql_connect 连接才能工作。另请参阅 - stackoverflow.com/questions/10750377/mysql-real-escape-string-with-pdo-php
  • @Sean 我的想法是 PDO 保护我与数据库的连接,但我不确定 php $hashed_pa​​ssword = crypt($Upassword, $bcrypt_salt) 中的恶意输入会发生什么。我提出了一个类似的问题,我使用 php 验证了用户输入,然后如果正确我会查询,购买答案是我错了stackoverflow.com/questions/13053318/…
  • @Gian 第一部分创建 salt + 加密代码,第二部分从数据库中检索 salt 并加密用户纯文本“输入”密码并检查其是否与第 1 部分相同。所以理论上完整加密/散列在第一部分完成,但在第二部分只完成散列。

标签: php encryption passwords bcrypt blowfish


【解决方案1】:

如您所见,我将代码分成 2 个 if 语句,这意味着在检查密码是否正确时未设置 Blowfish_Pre 和 $Blowfish_End。

解决方案要么在 if 语句之前设置此变量,要么使用设置它们两次。

希望它可以帮助某人。

【讨论】:

  • 感谢 Juan 的反馈,您可能会在一段时间后接受自己的答案。
猜你喜欢
  • 2017-10-31
  • 1970-01-01
  • 2019-06-28
  • 2015-05-14
  • 2019-10-11
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多