PHP登录无效(将普通提交的密码与加密密码进行比较)

时间:2015-06-11 02:57:55

标签: php mysqli login passwords

我试图使用预先准备好的语句进行登录但是仍然失败,所以当失败时我让每一步都有一个回音。我得到一个"密码验证:(0)"所以我猜测问题在于将普通提交的密码与数据库中的加密密码进行比较。所以我做了$ pass = sha1($ pass);但是我得到了同样的错误。我该如何解决这个问题?

中心舞台:

if(isset($_POST['pass'])){$pass=$_POST['pass'];}
if(isset($_POST['email'])){$email=$_POST['email'];}
$pass = sha1($pass);

if(password_verify($pass, $row['pass'])){

        $_SESSION['user'] = $_POST['email'];
        header('Location: somewer.php');
        exit();
    }else{
    echo "Password verify: (" . $stmt->errno .")" . $stmt->error;
}

整个php:

<?php
error_reporting(E_ALL);

$mysqli = new mysqli ('localhost', 'root', '', 'dbname');

if($mysqli->connect_errno > 0) {
die('Database [' . $mysqli->connect_error . ']');
}
ob_start();
session_start();
if(isset($_POST['pass'])){$pass=$_POST['pass'];}
if(isset($_POST['email'])){$email=$_POST['email'];}
$pass = sha1($pass);

if(isset($_POST['lsubmit'])) {

if(!($stmt = $mysqli->prepare("SELECT pass, email FROM users WHERE email = ?"))){
        echo "Prepare: (" . $mysqli->errno . ")" . $mysqli->error;
}

if(!$stmt->bind_param('s', $email)){
    echo "Bind: (" . $stmt->errno . ")" . $stmt->error;
}

if(!$stmt->execute()){
 echo "Execute: (" . $stmt->errno .")" . $stmt->error;
}

$userdata = $stmt->get_result();
$row = $userdata->fetch_array(MYSQLI_ASSOC);



$stmt->bind_result($pass, $email);
$stmt->store_result();

         if(password_verify($pass, $row['pass'])){

        $_SESSION['user'] = $_POST['email'];
        header('Location: somewer.php');
        exit();
    }else{
    echo "Password verify: (" . $stmt->errno .")" . $stmt->error;
}
$stmt->close();

}

$mysqli->close();
?>

2 个答案:

答案 0 :(得分:0)

您不会将用户键入的密码哈希到表单中,而是在用户实际注册到您的站点时使用两种不同的哈希方法哈希密码,password verify如果哈希是用{完成的话} {1}},请看一下这个问题Hashing and password_verify

答案 1 :(得分:0)

将我的一些评论写入答案,包括使用更安全的功能。

旁注:sha1并非被认为是最安全的密码哈希函数(不再)。

请参阅以下文章:

这里的问题是您正在混合使用两种不同类型的密码哈希方法。

sha1()password_verify()。那些不同的散列函数不会相互混合。 password_verify()仅与password_hash()一起使用。

所以,这个条件if(password_verify($pass, $row['pass'])){...}让你失望。

另外,我们不知道用于存储X-hashing方法的函数。

  • 从ircmaxell的答案之一中拉出来:

只需使用图书馆。认真。它们存在是有原因的。

不要自己动手。如果你正在创造自己的盐,你做错了。你应该使用一个为你处理这个问题的库。

$dbh = new PDO(...);

$username = $_POST["username"];
$email = $_POST["email"];
$password = $_POST["password"];
$hash = password_hash($password, PASSWORD_DEFAULT);

$stmt = $dbh->prepare("insert into users set username=?, email=?, password=?");
$stmt->execute([$username, $email, $hash]);

登录时:

$sql = "SELECT * FROM users WHERE username = ?";
$stmt = $dbh->prepare($sql);
$result = $stmt->execute([$_POST['username']]);
$users = $result->fetchAll();
if (isset($users[0]) {
    if (password_verify($_POST['password'], $users[0]->password) {
        // valid login
    } else {
        // invalid password
    }
} else {
    // invalid username
}

参考:https://stackoverflow.com/a/29778421/

参考文献:

脚注:

确保列足够长以容纳哈希值。使用varchar(255)是一个安全的选择,并且如果哈希值超过60,将确保将来使用。

来自手册:

PASSWORD_DEFAULT - 使用bcrypt算法(默认自PHP 5.5.0起)。请注意,此常量旨在随着时间的推移而变化,因为新的和更强大的算法被添加到PHP中。因此,使用此标识符的结果长度可能会随时间而变化。因此,建议将结果存储在数据库列中,该列可以扩展到超过60个字符(255个字符将是一个不错的选择)。

相关问题