繁体   English   中英

安全的PHP登录以防止重放攻击

[英]Secure PHP login against replay attacks

到目前为止,我一直在使用md5和sha1加密我的PHP登录中的密码,但由于这些算法现在被认为已经过时且不再安全,我想用PHP函数password_hashpassword_verify构建一个新的登录系统。 但是,有一件事我无法找到这些功能的解决方案:为了使登录安全抵御重放攻击,仅仅为每个密码设置一个单独的盐是不够的。 因为如果攻击者以某种方式窃听客户端和服务器之间的通信,他就可以像原始客户端一样将用户名和已加密的密码哈希发送到服务器。 所以我的解决方案一直是创建一个额外的“盐”(我不知道是否有一个我的意思的官方术语),这仅对单次登录尝试有效。 因此,客户端从服务器获取两个盐(一个对于每个用户帐户始终相同,另一个每次不同),加密用户输入的密码并将散列发送到服务器。 然后服务器检查此哈希值(例如$ Hash == sha1($ HashFromDbWithFixedSalt。$ RandomHash))。 然后创建一个新的$ RandomHash。 因此,即使攻击者模仿用户的通信,他也无法获得不允许的访问权限。

新的PHP函数确实支持salt,但我找不到用这两种方法实现旧解决方案的方法,因为DB中的哈希将包含固定哈希(每个用户帐户不同)但不包含随机哈希(仅适用于一次尝试)。 有没有人有想法或者已经解决了这个问题?

编辑:

这就是我以前的做法:

新用户注册:

  1. 为此用户创建随机盐。
  2. 将md5($ password_in_cleartext + $ salt)和salt本身保存到数据库中。

用户想要登录:

  1. 用户将其用户名发送到服务器
  2. 服务器从数据库中查找他的salt并创建一个额外的随机盐,它保存在$ _SESSION中。 它将这两种盐发送给用户。
  3. 用户在客户端(通过JS)加密他的密码,如下所示:sha1(md5($ password_in_cleartext + $ salt_from_the_db)+ $ random_salt)。 他将此哈希发送到服务器。
  4. 服务器检查sha1($ hash_from_the_db + $ random_salt)== $ hash_the_user_sent。 如果它们不相等,它会创建一个新的random_salt并将其发送给用户(返回步骤3)。

password_hash会自动为每个密码生成一个salt。

永远不会将散列密码传递给用户或离开服务器。 如果您担心流量嗅探或MITM攻击 ,请使用SSL / https。

听起来你也在努力防范CSRF攻击。 在这种情况下,您将在用户第一次点击页面时设置随机令牌,并期望随每个请求一起发送(这将阻止无法访问令牌的站点代表用户)。

如果您没有使用SSL,那么您的登录将不安全。 无论您使用的哈希算法多么不可逆,无论如何都有其他方法来破坏交互。

它不是你的哈希的大小,它是你用它做的事情。 使用md5的编写良好的系统将比使用sha2的编写错误的系统更安全。

假设您已经使用SSL和HSTS预注册,以及一些可缓存的ssl-stripping-sensitive CSS但仍然需要更高的安全性,或者您在具有远程SSL终止的共享服务器上运行,那么您当前的方法是有效的,您只需需要升级您的散列算法(以及分配用于存储散列密码的空间)。 但正如您所发现的那样,在应用会话盐哈希之前,您仍然需要回复存储盐+密码哈希(提示:会话ID是后者的良好熵源,但JavaScript不能访问会话值 - 生成会话ID服务器端的has以用作会话salt)。 然后问题变成了JavaScript中可用的哈希函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM