使用 Cookie 和 Salted Hashes 的 PHP 登录系统

Posted

技术标签:

【中文标题】使用 Cookie 和 Salted Hashes 的 PHP 登录系统【英文标题】:PHP Login system using Cookies and Salted Hashes 【发布时间】:2010-09-28 22:55:31 【问题描述】:

我正在开发一个基于 php 的登录系统。 每个用户都有一个 ID(一个数字)和一个密码,这些密码以盐渍哈希的形式存储。

我能够确定登录是否成功,但现在我需要将该信息存储在某处(以便用户不会永久注销)。

过去,我使用过 $_SESSION 变量。但是,这些似乎在用户离开浏览器时被删除,这是不希望的。 另外,我不能“假设”用户不会试图欺骗系统,所以它必须是安全的。

所以,这是我的问题:

    我应该使用$_SESSION 还是$_COOKIE?这些方法的主要优点是什么? 如何实现“记住我”复选框? 应将哪些信息存储在 session/cookie 变量中?

请注意,此特定问题未考虑任何数据库安全问题。

关于数字 3,我的意思是:

我应该将用户的 ID 和哈希密码存储在 cookie/会话中,还是 我应该将用户的 ID 和非哈希密码存储在 cookie/会话中,还是 我应该存储“SessionID”和密码(散列还是非散列?)还是 我应该存储“SessionID”、“ID”和密码(同样,哈希或非哈希)?

我想让我的网站尽可能安全、高效和用户友好。 如果采用基于 SessionID 的方法,我也会感谢您对如何将其存储在数据库中的一些解释。

提前谢谢你

编辑:Eran 和 Brian 的答案似乎是我需要的。不幸的是,我只能将其中一个标记为已接受。我会尝试继续实施,看看哪个更有用。

【问题讨论】:

您应该尽可能重用现有的身份验证框架,因为它复杂。例如,看看github.com/delight-im/PHP-Auth 【参考方案1】:

我想重申 Eran 的观点从不在会话或 cookie 数据中存储用户密码,甚至是密码的哈希值。

一般来说,我已经使用 Cookie 在网络应用程序中实现了记住我的功能。 blog post on the fishbowl 是有关构建“安全”持久登录系统的信息的一个好起点。 another Stack Overflow answer 已经提供了深入的答案。

如果您需要确保登录是安全的,您必须使用 https。这是因为如果 cookie 或会话未加密,它们可能会被窃取。

另一个值得遵循的好习惯是 2 级登录系统。您可以在亚马逊等网站上看到这一点,您可以在不登录的情况下将商品添加到购物车,但如果您想以某种方式结帐或编辑您的帐户,则必须再次输入密码。

【讨论】:

这篇后续文章更进一步:jaspan.com/improved_persistent_login_cookie_best_practice @jmucchiello 不幸的是,“改进”方案没有实际意义。另请阅读:***.com/questions/549/…【参考方案2】:

将 ID 存储在 $_SESSION 中,但不要存储散列或非​​散列密码。一旦用户登录并且 ID 保存在 $_SESSION 中,您就不再需要密码了。

【讨论】:

【参考方案3】:

对于敏感信息(即身份验证结果),仅使用会话。会话存储在服务器端,被破坏的可能性要小得多。

关于会话生命周期,默认为浏览器会话的生命周期 - 但您可以控制它。有几个设置会影响这一点:

session.gc_maxlifetime - 有效控制会话的生命周期。

session.gc_probability 和 session.gc_divisor 共同决定了会话垃圾回收的频率。

最后 - session.cookie_lifetime 控制会话 cookie 的生命周期(保存会话 id 的 cookie,因此不必通过 URL 传输)。它应该与 session.gc_maxlifetime 的值匹配。

此外,切勿将密码存储在会话或 cookie 中(即使是散列格式)。只是身份验证的结果。

【讨论】:

以上是关于使用 Cookie 和 Salted Hashes 的 PHP 登录系统的主要内容,如果未能解决你的问题,请参考以下文章

为基于Wildfly容器的身份验证生成salted /哈希密码

Salted hash password

ruby 在Ruby中安全实施salted PBKDF2密码哈希(请参阅https://crackstation.net/hashing-security.htm)

通过ZipArchive php获取损坏或空拉链

C#Redis哈希Hashes

Redis教程:Hashes数据类型