存储哈希用户名和密码在php变量安全


Is storing hashed username and password in php variable safe?

如果其他人有同样的问题,请在评论中关注下面的线程以进一步澄清

我对网络安全设置不是很了解。将散列的用户名和密码存储在变量内的php文件中是否合理?

例如,我有一个登录表单,在提交时它将用户名和密码散列到cookie中。然后将散列cookie与服务器上的散列变量进行匹配以允许访问。

这些也是单向哈希。

问题是不是在PHP中存储哈希值;虽然通常建议使用数据库。

问题使用哈希作为明文密码/秘密;这与任何明文密码没有什么不同。如果有人能够查看PHP源代码,他们就会有哈希值,因此'密码'。请记住,密码散列不是秘密,即使它们通常应该被保密1

相反,接受纯文本形式的用户名/密码——尽管使用SSL在连接上加密密码——并根据哈希值2验证这一点。在任何情况下都不是来自的用户信任的哈希,因为无法证明它是从生成的一个实际的秘密 一旦提交的用户名/密码在服务器上根据存储的哈希值验证了,则在上建立一个会话;正是这个不可猜测的每个会话的秘密,然后用于重新验证/授权用户的每个后续请求3。这是在PHP中创建新会话时"自动处理"的。

请参阅"注意事项"answers"不要自己编写密码检查器"的答案,这些答案尤其相关。


1在现实世界的应用程序中,应该有一个高的优先级给予机密性和防止未经授权的披露。这是因为大多数用户选择愚蠢的短密码或普通密码(至少在有机会的情况下),这些密码可以很快被暴力破解。这可以通过鼓励安全的密码短语使用和辅助验证器来缓解。

2应该使用较新的password_verify/password_hash(或等效的库/backport)函数,因为这些函数可以正确处理基本细节,包括

  1. 使用正确生成的盐来防止彩虹表攻击,

  2. 使用适当的(如。

  3. bcrypt)哈希函数,减轻对强密码/密码短语的暴力攻击。

(如果计划使用SHA -不要!-对于散列密码,停止并读取链接…)

3与使用散列作为密码不同,这只容易受到会话劫持的影响,即使PHP源代码中的散列被泄露:它也是每个会话唯一的。攻击者需要访问客户端的cookie(通过本地访问或跨站点脚本);XSS可以通过HTTP- only cookie缓解)或拦截HTTP请求的方法(可以通过HTTPS缓解);然后,在该会话中,攻击者可以模拟经过身份验证的客户端。


长话短说:如果需要将数据存储在cookie中(或与服务器请求一起发回)以确保数据一开始就来自服务器,一种解决方案是使用HMAC作为身份验证代码。但这并不适用于这里。

用户名/密码认证有一个经过良好测试的解决方案,不应该被修改。

存储密码时,使用PHP的password_hash函数。

password_hash("rasmuslerdorf", PASSWORD_DEFAULT)

是一个典型的用例。这就产生了人们粗略地称之为哈希的东西。它不是一个真正的哈希,因为它使用了bcrypt,一个密钥派生函数,但每个人都把它们称为哈希。将密码与用户名一起存储。您可以在数据库或平面文件中执行此操作。您应该尽最大努力保持这种安全,以防止离线攻击,但这种散列对于除了非常坚定和装备精良的攻击者之外的所有攻击者来说都是相对安全的。

用户登录时,将其用户名和明文密码传递给服务器。服务器应该使用用户名作为密钥获取用户存储的密码散列。然后服务器使用PHP的password_verify验证密码。

您在这里所做的只是用一个密码替换另一个密码。它很容易受到重放攻击。你将有效的密码存储在cookie中,这就打开了一个漏洞利用的世界。

网上有很多关于PHP身份验证的好教程,也有一些不好的。你应该:

  • 使用PHP会话(带会话cookie)

  • 使用https(和HSTS)

  • 将提交的值发送到服务器端进行验证

  • 在服务器上查找针对用户名存储的散列密码和随机盐

  • 用存储的盐对提交的密码进行散列

  • 如果与存储的哈希值匹配,则认证成功;重新生成会话id并继续。

  • 否则跟踪并限制失败尝试的次数,以防止暴力破解。

  • 提供一个显式的注销函数,删除$_SESSION

  • 中的数据

这还不够,但还是很好的开始

cookie仍然是一个安全问题,因为它可以用于攻击,因为哈希是稳定的结果,无论它是MD5或其他。

在Wordpress中,他们使用了一个很好的策略,即"盐密钥",这使得应用程序安全且难以被破解