【问题标题】:Is this user auth secure enough?此用户身份验证是否足够安全?
【发布时间】:2015-09-02 19:14:54
【问题描述】:

我正在尝试放弃使用 md5() 来存储和比较密码。所以我想开始使用password_hash()。

现在,我以前是怎么做的,我会将用户名和密码的 md5 存储在他们的会话或 cookie 中(如果他们选择“记住我”),然后检查数据库以查看是否存在任何用户使用该用户名和 md5 密码。我意识到这不是很安全,这就是为什么我想阻止它。

我不能再这样做了,因为 password_hash() 总是改变,所以我不能在他们的会话中存储一个哈希然后在数据库中检查它,因为我需要对未哈希的密码使用 password_verify。

所以我的问题是,如果我在用户成功登录时将散列的“会话 ID”和“令牌”存储在用户表中,然后将其与用户 ID 一起存储在个人会话/cookie 中,以便检查数据库,这是否足够安全?当我说散列的“会话 ID”和“令牌”时,我的意思是随机大数的 sha256'd 甚至 md5'd 散列......

例子:

用户登录 -> 哈希“会话 ID”和“令牌”存储在用户 cookie/会话中,并且他们在数据库中的行使用哈希“会话 ID”和“令牌”更新。

用户访问站点 -> 代码根据浏览器会话/cookie 变量检查他们的“会话 ID”和“令牌”是否存在于数据库中。如果是,则假定找到的行代表当前用户。

任何见解将不胜感激。

【问题讨论】:

  • 您可以使用加盐密码哈希。
  • @PraveenD - password_hash() 已经生成了一个加盐哈希......你到底在暗示什么?
  • 盐应该是随机的。
  • @PraveenD - password_hash() 生成一个加盐的散列,其中盐是随机的,每个散列已经...... OP 已经意识到这一点,也许如果你解释了你的意思
  • 静态盐完全抵消了使用密码哈希开始的效果。如果我打算这样做,我还不如坚持使用 md5()。

标签: php security authentication hash


【解决方案1】:

为了获得最佳密码哈希值和用法,但代码简单,如下示例...

$salts= ['cost' => 12]; password_hash("Password", PASSWORD_BCRYPT, $options);

$salts 是一个数组,它在使用password_hash() 时组合了多次。

PASSWORD_BCRYPT 是一种算法,它使用“$2y$”标识符和河豚加密算法对字符串进行哈希处理。这会输出 60 个字符的混乱集合。

【讨论】:

  • 你可以在$salts中添加任意数量的键⇒值
  • 请不要['salt' => 12],你要['cost' => 12]
  • 没错@Scott Arciszewski,我后来才意识到。使用['cost' => 12]
  • 这并没有解决 OPs 问题。虽然这对于密码散列是正确的,但问题是关于如何存储会话令牌,其散列必须是可搜索的并且不能包含随机盐。
【解决方案2】:

我要做的是当用户登录时,使用 uinqid() (http://php.net/uniqid) 为他的登录生成一个唯一 ID,然后将其存储在一个新表中。 id 然后检查这个表,看 cookie 是否与表中存储的 uniqid 匹配。

您必须确保在用户再次登录时删除表格行,但如果用户在多个设备上设置记住我,这会导致问题,因此我会在表格中设置过期日期对于每个 id,登录脚本将:

  1. SELECT * FROM 'UNIQIDS' WHERE $current_date_and_time > 'EXPIRE' 并删除所有结果
  2. 检查 cookie 是否存在。如果有一个并且它与 uniqid 匹配,则在计算机上创建一个会话,否则显示登录页面

用户登录时:

  1. 检查表中是否已经存在uniqid
  2. 如果存储了一个,如果当前日期和时间已超过其过期日期,则删除该行
  3. 如果一个已过期,则生成一个新的,其新的过期日期与您正在生成的 cookie 的过期日期相匹配。如果尚未过期,请计算从现在到过期的时间,并创建一个包含其值并在您计算的时间内过期的 cookie。

这是高度安全的,因为很难伪造这个 cookie,而且它永远不会将用户密码信息传递给客户端机器。

为了更加安全,您可以对您生成的 uniqid 进行 md5,但没有真正需要,因为它不包含重要信息。

这是相当复杂的,但如果你一步一步来,应该是不可能的。

祝你好运!

【讨论】:

  • 令牌在存储到数据库之前应该进行哈希处理,否则具有数据库读取权限的攻击者(SQL 注入)可以读取令牌并冒充用户。因为令牌(20+ 个随机字符)是一个非常强大的“密码”,所以可以使用像 SHA-256 这样的快速无盐哈希,这使得它们具有可比性。
  • 不一定。如果您从表中选择所有行,不让最终用户访问 SQL 语句,创建一个 assoc 并使用 for/loop 让 php 搜索 assoc,而不是让 mysql 在返回 assoc 之前搜索表,它离开对 SQL 注入无懈可击的表。在那之后,如果你的 SQL 被黑了,你会遇到比哈希安全更大的问题。
  • 不一定是对带有令牌的表的查询,它可以揭示哈希值,每个SQL语句都必须得到保护。看看我的tutorial 中的示例。如果您使用第三方库,您也必须测试此代码。即便如此,令牌也有其他方式丢失,丢弃的服务器、备份……
  • 对不起先生,您是对的。为了安全起见,应该对 uniqids 以及任何其他潜在的敏感信息进行哈希处理,但谨慎的做法是确保对 sql 注入采取预防措施,因为任何确定的黑客都可以在足够的时间破解哈希。还要确保您的 uniqid 和 cookie 经常过期,以防止有人通过重复创建具有不同值的虚假 cookie 来暴力破解您的系统。
猜你喜欢
  • 2013-03-02
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 2020-05-27
相关资源
最近更新 更多