【发布时间】:2015-12-09 12:00:02
【问题描述】:
堆栈溢出。
我正在尝试为我的网站创建一个登录系统,使用 PHP 的 password_* 函数进行密码哈希/验证,但即使我输入了正确的密码,password_verify() 也总是返回 false。
基本流程是: - 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() 没有。
我真的很感谢这里的一些帮助。 :)
谢谢。
【问题讨论】:
-
$_REQUEST_['password']似乎不对。$REQUEST['password']也没有。另外,请不要定义自己的盐。把它留给password_hash()。还有一个,$udata['password']用过一次,$udata[0]['password']在其他地方用过。 -
@Jon Stirling,抱歉,Stack Overflow 将其中的一些解析为 Markdown,这弄乱了一些代码。现在修复了格式问题。
-
你为什么要在散列之前转义密码。对不起,但这段代码到处都是。对此没有一个单一的答案。
-
另外,我只是在定义自己的 salt,这样我就可以在两个页面上验证密码没有被 HTTP 或任何东西破坏。 (就像我说的,非常不安全)一旦这段代码真正工作,我会让 PHP 做我的盐。 ;)
-
这很奇怪,因为我实际上是在哈希和验证时转义了密码,所以我应该得到相同的结果。
标签: php mysqli passwords php-password-hash