如何在PHP中安全地存储包含敏感数据的Cookie?

如何在PHP中安全地存储包含敏感数据的Cookie?,php,security,cookies,login,hash,Php,Security,Cookies,Login,Hash,我希望我的用户在登录我的网站时能够“让我保持登录”。根据本文顶部答案的建议,我决定将用户的salt和密码组合散列在一个cookie中,并将用户的id(一个数字)存储在另一个cookie中。当然,散列值也将存储在数据库服务器端,以便在用户再次返回时进行验证。我使用的salt值与我在用户首次注册时用于散列用户密码的salt值相同,因此它是静态的,在会话之间不会更改。我发现这种方法存在一些问题 1) 如果注册盐是静态的,那么使用注册盐是一个好主意吗?还是应该每次为cookie生成不同的注册盐 2) 如

我希望我的用户在登录我的网站时能够“让我保持登录”。根据本文顶部答案的建议,我决定将用户的salt和密码组合散列在一个cookie中,并将用户的id(一个数字)存储在另一个cookie中。当然,散列值也将存储在数据库服务器端,以便在用户再次返回时进行验证。我使用的salt值与我在用户首次注册时用于散列用户密码的salt值相同,因此它是静态的,在会话之间不会更改。我发现这种方法存在一些问题

1) 如果注册盐是静态的,那么使用注册盐是一个好主意吗?还是应该每次为cookie生成不同的注册盐

2) 如果有人访问cookie并将其复制到另一台计算机,然后尝试从该计算机访问网站,理论上,它会自动将其登录到该用户的帐户,这不是安全问题吗

3) 在某些恶意用户想要访问数据库的情况下,安全网站会对密码进行加密和哈希处理,使得黑客很难访问多个帐户(如果有的话)。但是,通过简单地处理散列值和salt值,并创建一个与他们在数据库中更改的值相匹配的cookie,他们可以有效地访问他们想要的任何帐户,从而使整个密码散列过程变得毫无用处。因此,我现在使用的这种cookie方法正在损害我的整个数据库和所有用户的帐户


所以我的问题是,我如何在PHP中存储cookie,其中包含敏感信息,例如用户密码的散列,而不必担心上述问题?当然,像Gmail和Hotmail这样提供“让我保持登录”功能的网站采用了比我现在所做的更安全的方法,那么他们会怎么做呢?

不将密码存储在cookie中,不管是否散列。事实上,没有理由在cookie中存储任何敏感信息。您只需将128位(或更大)的随机id映射到数据库中的用户帐户,并将该id存储在cookie中。有人不可能通过远程暴力猜出一个有效的id,特别是如果你有锁的话

如果有人访问cookie并将其复制到另一台计算机,然后尝试从该计算机访问网站,理论上,它会自动将其登录到该用户的帐户,这不是安全问题吗

对。这是该功能的缺点。但是,如果您的网站检测到新的IP地址(特别是来自不同国家的IP地址),并且需要第二步(向移动设备发送代码等),那么您将处理此问题以及密码被盗的一般问题。(这当然无助于防止本地网络攻击,比如不安全的公共wifi。)

一个更方便的解决方案是要求“记住我”cookie使用SSL。这样,黑客就不会在纯文本传输中看到cookie,可能需要进行本地攻击。(如果是这样,记住我的cookie可能是用户最不关心的。)

他们可以有效地访问任何他们想要的帐户,使得整个密码散列过程毫无用处

是的,也不是。如果你使用我描述的技术(随机id),那么他们只能访问具有“记住我”cookie的帐户。但也就是说,如果他们可以访问你的数据库,他们可以强行使用他们想要的任何帐户。如果密码本身很弱,即使是盐密码也很容易在本地破解

也可以考虑把“记住我”登录为半登录。购买物品、更改电子邮件地址等仍需要输入密码。做一些无害的事情,比如在留言板上发帖,可以不用密码

最后,请注意,PHP会话cookie只不过是一个临时的“记住我”标记!这在很大程度上适用于会话劫持的概念。“记住我”标志只是增加了一个更大的机会之窗


所以简而言之:不要在cookie中存储任何敏感信息,cookie需要SSL,如果可能的话,实现多因素身份验证。。。特别是对于管理员帐户。

回答得好,谢谢。因此,我将使用uniqid()之类的东西来生成一个用于记住登录名的令牌。如果数据库遭到破坏,攻击帐户会变得多么容易,我仍然感到不舒服。如果不包括整个“记住我”机制,我可能会检测到入侵并在任何严重损害发生之前采取行动,但使用此解决方案,攻击几乎是瞬间发生的。
uniqid()
while unique并不难预测。我会使用base64编码的
openssl\u random\u pseudo\u bytes()
。您的担忧是正确的,但同样,健全性检查可以防止广泛的攻击。e、 例如,如果有很多新IP登录到旧帐户,或者一个IP登录到多个帐户,请升起一个标志。