2017-08-25 63 views
1

背景 - 我已經花了最後一個小時左右查看各種帖子網站等,看看爲什麼我的密碼檢查功能突然停止工作。PHP password_verify false negative

每次我嘗試使用它時,它都會返回false,包括輸入的密碼是否正確。

我已經迴應了我的輸入和我的哈希,兩者都很好地匹配(通過比較表中的哈希和回顯的哈希)。

但是,當這些變量通過password_verify時,它將返回100%的錯誤時間。

我認爲是錯誤的? -基於a post from an external site,我認爲這是由於我的hashedPassword變量被解析的方式。當比較兩者時,變量類型中出現錯誤並返回false。

我的代碼和數據庫是什麼樣的? -

users表。包含其他列。

userId | username | password 
---------------------------- 
    1 | example | temp1 

包含密碼檢查功能的類。只是用password_verify,哈希匹配通過手動檢查它,你可以通過下面的輸出中看到之前(已削去的try/catch)

public function checkPasswordCorrect($username, $password) { // Returns true is the entered password is correct and false if it isn't. 

    // This creates a mysqli context to run the connection through. 
    $mysqli = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbPlusPlus); 

    // If there is an error connecting to the database, it will be printed and the process will close. 
    if (mysqli_connect_errno()) { 
     printf("Connect failed: %s\n", mysqli_connect_error()); 
     exit(); 
    } 

    $sql = "SELECT password FROM users WHERE username='$username'"; 
    $result = $mysqli->query($sql); 
    $row = $result->fetch_array(MYSQLI_ASSOC); 

    $hashedPassword = $row["password"]; 

    $mysqli->close(); 

    echo $password."<br>".$hashedPassword."<br>"; // The input is correct and the hash matches that in the table. 

    // We return a value of true or false, depending on the outcome of the verification. 
    if(password_verify($password, $hashedPassword)) { 
     echo "return true"; 
     return true; 
    }   
    else { 
     echo "return false"; 
     return false; 
    } 
} 

通過呼應$hashedPassword

temp0022 
$2y$10$9TgjJzSaqOB 
return false 

我在問什麼? -

  1. 有沒有檢查密碼輸入的更好的方法,更具體,我從表中拉動信息的方式(必須有這樣的一些簡單的方法)。

  2. 變量解析是否被指責?是否有任何文檔或文章可用於此主題,我還沒有看到?

我知道什麼? -我對mysqli的使用感到震驚,我對它很陌生。我也知道這裏有類似的答案,但似乎歸結爲某種語法錯誤比其他任何東西都多。

謝謝您花時間幫忙! :d

對於那些你們誰是擔心我會通過SQL注入攻擊被擊中的:因爲我已經修改了此示例代碼 大量使用準備,陳述我。感謝您對 的關注:)

+0

你允許多少個字符在數據庫中的'password'字段?它打印的密碼太短而被截斷。生成的密碼哈希(使用password_verity())長度約爲60個字符。如果你有一個更短的varchar字段,完整的散列將不會被保存。 –

+0

我覺得有點諷刺的是,你哈希你的密碼,但不要試圖阻止[SQL注入](http://bobby-tables.com/),就像你只希望你的系統的一半是安全的 – GrumpyCrouton

+0

[Little Bobby](http://bobby-tables.com/)說** [你有SQL注入攻擊風險](https://stackoverflow.com/q/60174/)**。瞭解[MySQLi](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php)的[Prepared Statements](準備語句)(https://en.wikipedia.org/wiki/Prepared_statement)。即使** [轉義字符串](https://stackoverflow.com/q/5741187)**是不安全的!我推薦'PDO',我[寫了一個函數](http://paragoncds.com/grumpy/pdoquery/#function),使它非常容易**,非常乾淨**,以及更多**安全**比使用非參數化查詢。 – GrumpyCrouton

回答

3

檢查您的表格結構。您的散列字段需要長度爲60(對於PASSWORD_BCRYPT)或255(對於PASSWORD_DEFAULT)(ref)來保存整個散列。你從數據庫中得到的長度是18個字符。你可能把它當作VARCHAR(18),所以在保存時會被截斷,這就是爲什麼你沒有得到一個匹配。

編輯:增加了PASSWORD_DEFAULT算法的長度。謝謝@ Don'tPanic。

+0

非常感謝! <3 – Will

+1

[The PHP documentation](http://php.net/manual/en/function.password-hash.php)推薦的長度爲255. –

+0

@不要Panic我會編輯它,注意它沿着BCRYPT長度。謝謝! – ishegg