Невозможно сравнить пароли BCRYPT

Я следую руководству на этом веб-сайте http://www.gregboggs.com/php-blowfish-random-salted-passwords/, но по какой-то причине при проверке того, совпадают ли пароли, это не удается.

HTML простой, 2 формы: одна для создания учетных записей, а другая для проверки. код можно увидеть здесь http://jsfiddle.net/Xf2Tc/

В качестве вывода я получаю: соль = соль в базе данных пароль в базе данных: $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();
    }
}
?>

person Juan    schedule 11.11.2012    source источник
comment
Используйте password_compat, это упростило процесс хэширования паролей с помощью BCRYPT   -  person Baba    schedule 11.11.2012
comment
Я не понимаю бит перешифрованного пароля в вашем вопросе. Это даже отдаленно не похоже на то, что его сгенерировал тот же алгоритм.   -  person Gian    schedule 11.11.2012
comment
Есть ли причина, по которой вы используете mysql_real_escape_string для $_POST['Upassword'] и $_POST['account']? Поскольку вы используете PDO, он автоматически избегает ваших данных, и, скорее всего, ваши $Upassword и $account сейчас не такие, как вы думаете, поскольку для работы вам нужно открытое mysql_connect соединение. см. также - stackoverflow.com/questions/10750377/mysql-real-escape-string -с-pdo-php.   -  person Sean    schedule 11.11.2012
comment
@Sean Моя идея состоит в том, что PDO защищает мое соединение с моей базой данных, но я не уверен, что произойдет с вредоносным вводом внутри php $hashed_password = crypt($Upassword, $bcrypt_salt). Я задал аналогичный вопрос, в котором я проверял ввод пользователя с помощью php, а затем, если он был правильным, я запрашивал ответ на покупку, что я был неправ stackoverflow.com/questions/13053318/   -  person Juan    schedule 11.11.2012
comment
@Gian Первая часть создает соль + шифрует код, вторая часть извлекает соль из базы данных и шифрует пароль пользователя для ввода в виде обычного текста и проверяет, совпадает ли он с частью 1. Таким образом, теоретически полное шифрование/хеширование выполняется в первой части, но в части 2 выполняется только хеширование.   -  person Juan    schedule 11.11.2012


Ответы (1)


Как видите, я разделяю свой код на 2 оператора if, что означает, что мои Blowfish_Pre и $Blowfish_End не устанавливались при проверке правильности пароля.

Решение: либо установить эти переменные перед оператором if, либо использовать их дважды.

Надеюсь, это поможет кому-то.

person Juan    schedule 11.11.2012
comment
Спасибо, что сообщили, Хуан, через некоторое время вы можете принять свой собственный ответ. - person Maarten Bodewes; 12.11.2012