2017-02-17 137 views
0

我的PHP應用程序/數據庫設置需要散列和反密碼的密碼。雖然password_hash()似乎向數據庫提供了正確的輸出,但使用password_verify()將存儲的散列與明文密碼進行比較會提供FALSE結果。PHP password_verify()不驗證密碼

基本輸入形式(signup_form)或(login_form):

<form action="sign_verify.php" method="post"> 
    <input id="email_add" class="field" type="text" placeholder="Email" name="email"><br> 
    <input id="password" class="field" type="text" placeholder="Password" name="pword"><br> 
    <input type="submit" value="Sign Up"> 
</form> 

散列和添加到數據庫(signup_verify):

$temail=trim(filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING)); 
$tpword=trim(filter_input(INPUT_POST, 'pword', FILTER_SANITIZE_STRING)); 
if (!filter_var($temail, FILTER_VALIDATE_EMAIL)) { 
    echo "Invalid email address"; 
} 
else { 
    $link = array("Database"=>dbName, "UID"=>userName, "PWD"=>userPassword, "MultipleActiveResultSets"=>true);  
    sqlsrv_configure('WarningsReturnAsErrors', 0); 
    $link = sqlsrv_connect(serverName, $link); 
    if($link === false){ 
     echo "Connection Failed.<br>"; 
     die(print_r(sqlsrv_errors(), true)); 
    } 
    else{ 
     $hpword=password_hash($tpword, PASSWORD_DEFAULT); 
     $insertSql = "INSERT INTO Card_score_storage.dbo.customer_cards (Email,Password) VALUES (?,?)"; 
     $params = array(&$temail,&$hpword); 
     $prepareStatement = sqlsrv_prepare($link, $insertSql, $params); 
     if ($prepareStatement === false) { 
      echo "Looks like something went wrong."; 
      echo "<br>"; 
      die(FormatErrors(sqlsrv_errors())); 
     } 
     else { 
      if (sqlsrv_execute($prepareStatement) === false) { 
      echo "Looks like something went wrong."; 
      echo "<br>"; 
      die(print_r(sqlsrv_errors(), true)); 
     } 
     else{ 
      echo "You have successfully signed up with the email: $temail <br>"; 
      echo "<a href='index.php'>Return to our main page</a>"; 
     } 

Password_verify()驗證在用戶登錄(login_verify):

require_once 'config.php'; 
error_reporting(E_ALL); 

$email=trim(filter_input(INPUT_POST, 'email', FILTER_SANITIZE_STRING)); 
$pword=trim(filter_input(INPUT_POST, 'pword', FILTER_SANITIZE_STRING)); 

//Connect to user database 
$link = array("Database"=>dbName, "UID"=>userName, "PWD"=>userPassword, "MultipleActiveResultSets"=>true);  

//Check for connection error 
sqlsrv_configure('WarningsReturnAsErrors', 0); 

$link = sqlsrv_connect(serverName, $link); 
if($link === false){ 
    echo "Connection Failed.<br>"; 
    die(print_r(sqlsrv_errors(), true)); 
} 
else{ 
    sleep(0.2); 
    $LoginFetchSql= "SELECT Email,Password FROM Card_score_storage.dbo.customer_cards WHERE Email = '$email'"; 
    $stmt_l=sqlsrv_query($link,$LoginFetchSql);  
    $getuser = sqlsrv_fetch_array($stmt_l, SQLSRV_FETCH_ASSOC); 

    if ($getuser["Email"] ==NULL) { 
     echo '<p style="text-align:center">You did not login successfully.</p>'; 
     session_destroy(); 
    } 
    else{ 
     echo $getuser["Password"],"<br>"; 
     $verify=password_verify($pword,$getuser["Password"]); 
     if($verify){ 
      echo"Good password."; 
     } 
     else{ 
      echo"Bad Password."; 
     } 
    } 

} 

存儲哈希密碼的數據庫列是大小爲255的NCHAR。替換第使用直接POST值進行過濾/修飾輸入,如$ _POST [「pword」]提供相同的結果。

+0

'$ getuser'的股票價值? – C2486

+0

**使用「[email protected]」的電子郵件和「test」的密碼:** Array([Email] => [email protected] [Password] => $ 2y $ 10 $ f2cLGYqlLQf6gniX7JyhvOaSIQANy8qIkmLcly/0wBxdcYFLTxs8m ) – cavanaugh

+0

您確定您傳遞的數據與您存儲在數據庫中的「$ pword」值相同嗎? – C2486

回答

0

我認爲你的問題發生在從數據庫寫入/檢索時。我建議var_dumping註冊的密碼,當你檢索並比較這些密碼。

編輯:將nchar更改爲varchar應該修復它。這是因爲NCHAR 可以商店unicode數據(這可能導致驗證返回false)並具有固定長度。 VARCHAR 不能存儲unicode數據並具有可變長度。

僅供參考退房有關更多信息,這個問題#1:What is the difference between char, nchar, varchar, and nvarchar in SQL Server?

+0

新的測試顯示初始密碼散列,存儲在數據庫中的值和檢索到的值完全相同。什麼時候會出現假想的寫作/檢索問題? – cavanaugh

+0

你可以嘗試使用VARCHAR而不是NCHAR嗎? –

+0

顏色我驚訝,修復它。你能否猜測問題是什麼? – cavanaugh