2017-05-07 59 views
0

我想讓我的頁面更安全,我開始使用它的密碼加密部分。我試圖實現password_hash +密碼驗證,但到目前爲止,我沒有成功完成整個工作。所以,這是在我的登錄區域:PHP password_verify不對數據庫工作

$username = mysqli_real_escape_string($connection, $_POST['username']); 

$password = mysqli_real_escape_string($connection, $_POST['password']); 

$query = "SELECT username, password FROM `users` WHERE username='$username' and user_enabled='1'"; 
$result = mysqli_query($connection, $query) or die(mysqli_error($connection)); 
if($row = mysqli_fetch_assoc($result)) { $dbpassword = $row['password']; } 

if(password_verify($password, $dbpassword)) { 
    echo "Successful login"; 
}else{ 
    echo "Invalid Login Credentials."; 
} 

我總是收到無效的登錄憑證。

當我修改該用戶的新密碼,我做了以下內容:在數據庫

$pass = mysqli_real_escape_string($connection, $_POST['password']); 
$options = [ 'cost' => 10, 
      'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), 
      ]; 
$password = password_hash($pass, PASSWORD_BCRYPT, $options)."\n"; 

$query = "UPDATE users 
      SET `password` = '".$password."' 
      WHERE id = ".$_POST['user_id']." 
      "; 

$result = mysqli_query($connection, $query) or die(mysqli_error($connection)); 

密碼爲VARCHAR(255),它是存儲這樣的:

$2y$10$Y5HIyAsLMfkXIFSJONPsfO3Gxx3b46H.8/WFdLVH3Fqk2XNfy2Uaq 

我在這裏做錯了什麼?

+0

調試每一步的方法; 'var_dump($ password)'在哈希之後,在數據庫中檢查它,在將它從數據庫中拉出後檢查它。它在任何階段都完全改變......?對你想驗證的密碼做同樣的處理。 – deceze

+2

並學習使用預準備語句和綁定參數,而不是使用SQL注入式字符串連接。 – deceze

+0

我剛剛確認在更新數據庫之前創建的密碼與存儲在數據庫中的密碼相同,並且與登錄時從數據庫中拉出的密碼相同。 – cbarg

回答

6

\n在下面一行中,嵌入了一個換行符(編輯:一個不能包含在用戶輸入的密碼中)

$password = password_hash($pass, PASSWORD_BCRYPT, $options)."\n"; 

您需要刪除它並重新使用新的散列。

Jay Blanchard,關於它的一個成員Stack submitted a note關於它不太長也在password_hash()手冊,這是他和我實際上談論的東西。

echo password_hash("rasmuslerdorf", PASSWORD_DEFAULT)."\n";

人們正在存儲該散列與:

利用來自串接換行符\n到哈希的端部的文件,即,例如,當要小心級聯換行符並因此password_verify()將失敗。

另一種選擇是使用trim();這也是有效的(在哈希時刻)。

$password = password_hash($pass, PASSWORD_BCRYPT, $options)."\n"; 
$password = trim($password); 
// Store in db after 

然而,你仍然需要重新清除舊的散列和創建新的散列。

但請記住,你不應該逃避密碼。

其中一個例如123'\abc(完全有效)將被修改爲123\'\abcreal_escape_string();這不是必需的。 password_verify()照顧,安全明智。

+0

哇,就在硬幣上!我從來沒有看到這個評論。非常感謝@Fred -ii- – cbarg

+1

@cbarg不客氣。傑伊在不久之前提交了該說明。他和我談到了提交一張紙條,所以他繼續做下去,這是經常被忽視的。如果你可以在手冊中爲[Jay's note](http://php.net/manual/en/function.password-hash.php#121017)註冊,那麼它會有所幫助http://php.net/manual/en /function.password-hash.php - 該說明早已過期,希望其他人可以閱讀用戶提供的備註。 * Cheers * –

+0

如果只是添加換行符,數據庫中的REPLACE()應該能夠修復它。散列本身是正確的。 – tadman