【问题标题】:Password safety in PHPPHP中的密码安全
【发布时间】:2014-07-24 05:32:18
【问题描述】:

我主要开发 HTML/CSS 网页,我正在开发一个网页,在该网页上,用户需要保护网页密码以防窥探。该页面仅用于发布非机密信息,例如私人成员活动和日程安排。我知道 PHP 的基础知识,并且想使用它,但我担心安全性。该页面将有多个用户,但它只需要一个所有用户都可以使用的密码。它也是一个流量相当低的网站,因此在这种情况下,它不需要 100% 安全,但我希望它尽可能安全,没有太多麻烦。

到目前为止,当用户尝试访问成员页面时,我有一个登录页面,带有密码输入字段,它将结果发布到名为(示例名称)verifypassword.php 的页面

这个文件看起来像这样:

$password = ("mypass");

$passresult = $_POST["password"];
$passresult = strip_tags($passresult);
$passresult = htmlspecialchars($passresult);

if ($passresult != $password) {
die("Invalid password.");
}

elseif ($passresult == &password) {
setcookie("mycookie");
header("location: member-page.php");
}

else {
die("Unknown Error")
}

然后,在会员页面的顶部,我有几行PHP代码如下:

$userloggedin = $_COOKIE["mycookie"];

if (!isset ($userloggedin)) {
die("Please log in to view this page");
}

如果用户未登录,文件和值本身会通过 die 函数隐藏,但密码和 cookie 仍在服务器上传输。 我曾尝试阅读有关对密码值进行加盐和散列的内容,但对这种事情不熟悉。我应该怎么做?有没有我可以阅读的教程或资源?我尝试在 Google、php.net 上查找,当然还有在 stackoverflow 上查找,但除了创建一个数据库来存储多个用户生成的密码之外,我找不到任何处理密码的东西,这不是我需要的。

我目前正在使用 WAMPP。

【问题讨论】:

标签: php password-protection


【解决方案1】:

如果您想遵循最佳实践,代码的第一行应该如下所示:

$hash = '$2y$10$zRg5l/v9gzD/aICnp/GUlu/rFv/0ZNvxX/A5v86zjepZmuRWWL6IG';

请注意,我们以纯文本形式存储哈希而不是密码。这些哈希以下列方式生成:

password_hash("test", PASSWORD_DEFAULT);

我们为什么要这样做?因为如果您的数据库(或代码,在这种情况下)以某种方式被访问,那么您不希望您的密码也被盗。内置的密码处理功能尽可能地减轻了这种情况。

在检查密码方面,您必须确保用户必须以一种或另一种方式通过互联网发送密码!如果这对您来说是一个大问题,您可以使用 SSL 来缓解这种情况 - 最好始终使用 SSL 进行至少身份验证。这意味着如果有人拦截了您的用户和您的网站之间的连接,他们将只能看到加密数据。不管怎样,到货时你会检查如下:

// Assuming single password:
if ( password_verify( $_POST['password'], $hash ) ) {
    // correct! 
    // the plain text in $_POST['password'] is the same as the plain text used to generate $hash
}

好的,那么,接下来。 Cookies 作为header 在浏览器和服务器之间发送。这些可以由客户端任意设置。因此,如果您依赖诸如 $_COOKIE['mycookie'] 之类的 cookie 来验证用户身份,那么有人可以发送一个手动制作的 Cookie 标头来模拟登录的效果。解决这个特定问题的方法是使用 sessions。在每个脚本的顶部,您运行session_start(),它会设置自己的cookie。此 cookie 不包含任何信息,只是一个随机生成的唯一 ID。 PHP 存储信息并将其与该 ID 相关联(通过 temp 文件夹中的文件) - 但客户端本身无法查看该信息的实际内容 - 或更改它。

要将信息添加到会话中,请将其放入 $_SESSION 超全局中,如下所示:

$_SESSION['logged_in'] = password_verify( $_POST['password'], $hash );

password_verify 将在密码匹配时返回 true,否则返回 false,因此您可以依靠它来正确设置布尔值。

所以你可以为login.php重写你的代码如下:

session_start();

$hash = '$2y$10$zRg5l/v9gzD/aICnp/GUlu/rFv/0ZNvxX/A5v86zjepZmuRWWL6IG';

if ( isset($_POST['password']) ) {
    // Assuming single password:
    if ( password_verify( $_POST['password'], $hash ) ) {
        // correct!
        header('Location: /member-page.php');
    }
}
// display login form

在会员页面的顶部:

session_start();

if (empty($_SESSION['logged_in'])) { // checks if it's set and if it's false
    die("Please log in to view this page.");
    header('Location: /login.php');
}

n.b.我重写了我的答案,因为我意识到它并没有很好地回答你的许多问题:)

【讨论】:

  • 你不是说session_start()吗?此外,有关如何使用 password_hash 和 password_verify 函数的示例也会很有用。
  • 所以我会使用 session_start(),而不是设置 cookie? password_hash 和 password_verify 函数在哪里适合?
  • 我编辑以提供示例并描述密码哈希的功能。
  • 当我尝试使用 password_hash 和 password_verify 时,它给了我一个未定义函数的错误消息。是否需要使用 wampp 启用附加或扩展,或者我在使用这些功能时遗漏了什么?我尝试按照php.net 上的说明进行操作,但无济于事。对不起,如果这听起来很幼稚,但我对这种事情真的不太了解。感谢您的所有帮助!
  • 我刚刚检查并 wampp 发布了 PHP 5.4 - 但这些函数是在 PHP 5.5 中添加的。最好保持最新,因为 PHP 在每个版本中都在管理一些相当严重的性能改进 - 但如果失败了,您可以下载这个为 PHP 5.5 提供向后兼容性的脚本。 github.com/ircmaxell/password_compat/blob/master/lib/…
【解决方案2】:

您可能不应该使用 Cookie 来执行此操作,因为它们可以在客户端伪造。会话变量可能会更好一些,但如果你想尝试保持简单,我可能会用一些盐对密码进行 MD5 并将其存储在 cookie 中,然后在尝试访问时检查你的 MD5ed 密码+盐再次访问该页面。

所以在我的头顶上是这样的:

<?
$password = ("mypass");
$salt = "makeUpASaltHere";

$passresult = $_POST["password"];
$passresult = strip_tags($passresult);
$passresult = htmlspecialchars($passresult);

if ($passresult != $password) {
die("Invalid password.");
}

elseif ($passresult == &password) {
setcookie("mycookie",md5($password.$salt));
header("location: member-page.php");
}

else {
die("Unknown Error")
}
?>

将它放在一个单独的文件中,然后使用 require() 将它包含在所有会员页面的顶部。

<?
$password = ("mypass");
$salt = "makeUpASaltHere";

$userloggedin = $_COOKIE["mycookie"];

if ($userloggedin == md5($password.$salt)) {
die("Please log in to view this page");
}

?>

仍然不如使用会话变量好,但至少有人不能随便创建“mycookie”并进入。此外,它还有一个优点是如果你要更改密码,它会自动注销所有已经登录的人。

【讨论】:

  • 使用这个,$salt 的例子是什么?
  • 任何随机字符串都可以。加盐的目的是确保试图猜测您的密码的人不能只对他们的猜测进行 md5 并根据 cookie 值进行检查。
猜你喜欢
  • 2011-07-11
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 2016-03-14
  • 2010-09-28
相关资源
最近更新 更多