2015-12-09 2 views
0

Переполнение стека.PHP password_verify() возвращает false, когда это должно быть правдой

Я пытаюсь сделать систему входа для своего сайта, используя функции password_* PHP для хэширования/проверки пароля, но password_verify() всегда возвращает false, даже когда я ввожу правильный пароль.

Основной поток: - Hash пароль в signup.php (используя предустановленную соль для тестирования)

Я знаю, что это чудовищно небезопасно (я затянуть его, когда он работает), но вот мой тест код.

хэширования: (signup.php)

<?php 
// include my custom MySQL function (it definitely works fine) 
if($_REQUEST['username'] && $_REQUEST['password']): 

    $db = connectMySQL(); // custom function, returns mysqli object for my DB 
    if($db->connect_errno > 0){ 
     die('Unable to connect to database [' . $db->connect_error . ']'); 
    } 

    $username = $db->escape_string($_REQUEST['username']); 

    $password = $db->escape_string($_REQUEST['password']); 

    $sql = $db->prepare("UPDATE `users` SET `password` = ? WHERE `username` = ?"); 

    $hashed = password_hash($_REQUEST_['password'], PASSWORD_DEFAULT, array("cost" => 10, "salt" => "PleaseDoNotTellAnyoneMySalt!")); 

    echo "<pre>".$password." Hashed: <pre>".$hashed."</pre><br><br>"; 

    $sql->bind_param('ss', $hashed, $username); 

    if(!$sql->execute()){ 
     die('There was an error running the query [' . $db->error . ']'); 
    } else { 
     echo "Successfully executed SQL"; 
    } 

else: ?> 

<form method="GET" action="signup.php"><!--HORRENDOUSLY INSECURE--> 
    Username: <input type="text" name="username"><br> 
    New Password: <input type="password" name="password"><br> 
    <input type="submit"> 
</form> 

<?php endif; ?> 

Проверка: (login.php)

<?php 

if($_REQUEST['username'] && $_REQUEST['password']): 

    $db = connectMySQL(); 

    if($db->connect_errno > 0){ 
     die('Unable to connect to database [' . $db->connect_error . ']'); 
    } 

    $username = $db->escape_string($_REQUEST['username']); 

    $password = $db->escape_string($_REQUEST['password']); 

    $sql = $db->prepare("SELECT * FROM `users` WHERE `username` = ?"); 

    $sql->bind_param('s', $username); 

    if(!$sql->execute()){ 
     die('There was an error running the query [' . $db->error . ']'); 
    } 

    $result = $sql->get_result(); 
    $udata = array(); 
    while ($data = $result->fetch_assoc()) { 
     var_dump($data);echo "<br><br>"; 
     $udata[] = $data; 
    } 

    echo "<pre>"; 

    var_dump($udata); 

    echo "</pre>"; 

    echo "Password verify says <pre>";var_dump(password_verify($password, $udata['password'])); 

    echo "</pre><br>PW: <pre>".$password."</pre>/Hash: <pre>".$udata[0]['password']."</pre><br>"; 

    echo "Entered password:";var_dump($password);echo "<br>"; 

    echo "Hash SHOULD be:";var_dump(password_hash($_REQUEST_['password'], PASSWORD_DEFAULT, array("cost" => 10, "salt" => "PleaseDoNotTellAnyoneMySalt!"))); echo "<br>"; 

    if(password_verify($password, $udata[0]['password'])): 
     echo "you are who you say you are"; 
    else: 
     echo "wrong password, <a href='?'>try again</a>"; 
     echo "Password algo info:";var_dump(password_get_info($udata[0]['password']));echo "<br>"; 
    endif; 

else: ?> 

    <form method="GET" action="login.php"><!--INSECURE, USE POST AFTER TESTING--> 
     Username: <input type="text" name="username"><br> 
     Password: <input type="password" name="password"><br> 
     <input type="submit"> 
    </form> 

<?php endif; ?> 

Хеш определенно хранится прямо в БД и, безусловно, будет получен хорошо, это просто password_verify() не имеет ни одного из них.

Я бы очень признателен за помощь здесь. :)

Спасибо.

+3

'$ _REQUEST _ ['password']' не кажется правильным. Также не запрашивается '$ REQUEST ['password']'. Кроме того, пожалуйста, не определяйте свою соль. Оставьте это до 'password_hash()'. И еще один, '$ udata ['password']' используется один раз, где '$ udata [0] ['password']' используется в другом месте. –

+0

@ Джона Стирлинга, извините, Stack Overflow проанализировал некоторые из них как Markdown, который испортил некоторые из кода. Исправлена ​​проблема с форматированием. – jsa

+0

И почему вы избегаете пароля перед хэшированием. Извините, но этот код повсюду. На это нет ни единого ответа. –

ответ

1

Список пару пятнистых вопросов в коде:

Использование $_REQUEST_['password'] вместо $_REQUEST['password'].

Использование $udata['password'] вместо $udata[0]['password'] (относится только к отладке).

В соответствии с комментариями основной проблемой был первый элемент, когда (я думаю) генерировал хэш.

Смежные вопросы