2017-02-17 154 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