【问题标题】:Handling expiration & validation of 2FA codes [closed]处理 2FA 代码的到期和验证 [关闭]
【发布时间】:2021-03-30 10:28:23
【问题描述】:

我目前正计划实施 2FA,要求用户通过 SMS 提供代码以执行某些操作,例如登录。我还将使用 Google Authenticator 等工具,但我不希望用户强制下载应用程序,这就是为什么我还需要通过 SMS(或可能的电子邮件)发送代码。

到目前为止我的计划是:

  1. 用户想要登录并请求验证码
  2. 后端生成一个数字代码,将其存储在 DB 中,并将数据库条目的 ID(或选择器)返回给前端
  3. 前端在用户电子邮件和密码旁边显示一个代码输入字段
  4. 代码通过短信/电子邮件发送给用户
  5. 用户现在有 5 分钟的时间将选择器 + 代码 + 电子邮件 + 密码发送到所有这些都得到验证的后端

关于这个的2个问题:

1) 处理代码过期

我的第一个想法是将代码仅像密码一样存储在数据库中,但我必须自己实现 5 分钟到期。当然我可以添加另一个带有时间戳的列来检查过期时间,但我宁愿选择更安全的东西。

现在我正在考虑将代码存储在数据库中 json Web 令牌的声明对象中,并将此令牌的到期时间设置为 5 分钟。因此,在 5 分钟结束后,解析 Web 令牌以将其与用户发送的代码进行比较失败。这将允许我在发生攻击情况时仅更改网络令牌的秘密,所有现有代码将立即失效。

这是一个好方法吗?或者你们认为这有什么问题,或者有没有更好的方法来处理它?或者是否也有一个用于哈希密码的库?

2) 验证和处理暴力攻击

由于我只想向用户发送 6 位或最多 8 位数字代码,因此我必须实施某种针对暴力攻击的保护(假设攻击者知道用户的电子邮件和密码)。

我想做什么:

  1. 如果发送了一次无效代码,则增加该特定代码 db 条目的失败尝试次数 += 1
  2. 如果代码超过 3 次失败尝试,则使数据库中的代码无效并要求用户请求新代码
  3. 当用户请求新代码时,让他等待 1 分钟才能请求新代码,将最后一次失败尝试的日期作为时间戳存储在用户数据库条目中以及 1 分钟延迟
  4. 如果第三个代码失败,存储新的时间戳并将延迟加倍到 2 分钟 ... 等等。在 3 个失败的代码之后,还需要一个 JS 挑战(Google Recaptcha)。
  5. 重试 5 次后,我将锁定帐户并等待用户与我们联系。

这是一种处理代码验证的安全方法吗?

【问题讨论】:

  • 我想知道您是否考虑过采用其中一种身份验证即服务系统? Onelogin、Okta、Ping、Auth0 等。您将能够直接处理 FIDO 密钥、SMS 2f、各种联合系统等。
  • 还有,别忘了一定要提前验证短信号码,防止作恶者欺骗验证。
  • 嘿琼斯,当然,用户必须在注册时验证设备。是的,我考虑过其中一些服务,但大多数都有缺点。有些需要应用程序,有些不能通过电子邮件发送令牌,有些价格昂贵,其中大多数都在美国存储数据,在那里会遇到一些 GDPR 问题。另外,我想了解自己构建它的问题在哪里,看看我的方法是否正确:)

标签: security jwt brute-force two-factor-authentication


【解决方案1】:

我认为您使用 JWT 过度保护了您的六位数验证码。

无论您如何管理它们,您都必须在它们过期或使用时使它们失效。一个很好的方法是在表中为每个代码提供一行,包括过期时间戳。然后在用户显示代码时删除代码行。每当您查找这些代码时,请在查询中添加 WHERE expires > NOW()。并定期删除过期行。

抵抗蛮力攻击很简单。当您准备好向用户发送代码时,您已经验证了他们的密码,因此您知道他们假装是谁。因此,只需跟踪该用户猜测代码的尝试。正如你所建议的,给他们三个尝试。然后让他们请求另一个代码。如果他们在一个日历日内重新请求超过五个代码,请将它们锁定到下一个日历日。

顺便说一下,这个方案对于生成各种随机数很有用。 (数字使用一次。)Nonce 可用于多种用途,例如通过电子邮件重置密码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-29
    • 2022-09-24
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 2019-07-18
    • 2011-08-01
    • 1970-01-01
    相关资源
    最近更新 更多