接受当前和以前的一次性密码是一种不好的做法吗?

信息安全 验证 多因素 一次性密码 顶部
2021-09-10 04:47:17

我经常看到使用一次性密码 (OTP) 实现的双因素身份验证 (2FA) 方法,其中当前(以前的),有时甚至 2 或 3 个以前的令牌仍然有效。这样做可能有几个原因,我能想到:

  • 克服客户端和服务器之间可能的时间同步问题(用户体验),
  • 为了方便系统管理员不要经常收到有关无法登录的支持电话。

接受以前的 OTP 是一种不好的做法吗?如果是这样,关于实施此类“功能”的一般建议是什么?

如果我错了,请纠正我,但当令牌为 6 位时,可能的组合数为 1.000.000 (000000 - 999999)。因此,在 30 秒的时间跨度内,只有百万分之一的令牌被接受。但是当接受以前的(甚至更多以前的)代币时,机会基本上是百万分之二、三、四或五。

2个回答

如果之前的意思是 OTP 早于用户已经通过身份验证的 OTP,那么是的,这被认为是不好的做法。OTP 旨在使用一次,因此得名。2FA 的全部意义在于它代表了安全三位一体中的“你拥有的东西”。允许令牌被使用两次违背了 OTP 旨在防止的目的。把它变成“你知道的东西”,这使它成为第二个密码。

这个问题通常不会表现为蛮力问题。例如,在时间窗口相对较短的 TOTP 的情况下,暴力破解并没有真正用来规避它。对于允许重用 OTP(当前或过去)的站点,作为攻击者的用例是拦截。

如果客户端使用 OTP 并且以某种方式被拦截,则攻击者现在将问题归结为用户名密码。其中,如果他们正在拦截信息,则可能也在监听这些信息。

在 HOTP 的情况下,问题更严重,因为理论上计数器或移动因子不会经常增加。这意味着用户通过身份验证的最后一个甚至上一个 OTP 可能会在很长一段时间内有效。在某些情况下,取决于服务器的执行情况。

如果之前的意思是在当前生成但尚未使用的 OTP 之前或之前的 OTP,那么不,在限制范围内。OTP 的标准实现通常应用“窗口”来克服同步问题。在 TOTP 的情况下,使用了 5 秒的窗口(向前和向后),但是在我见过的任何实现中,这总是不允许在用户验证的最后一个或之前的任何 OTP。如果我们以 15 秒的移动步骤和 15 秒的窗口为例,在 45 秒的时间范围内,将有 3 个 OTP 可用于进行身份验证,一个在过去,一个现在,一个在未来(假设时间间隔相同)作为移动步骤)。这背后的原因在@cornelinux 的回答中得到了优雅的解释。

对于 HOTP,该窗口是一个“前瞻”窗口。如果用户验证的最后一个 OTP 在接受的前一个 OTP 的下 10 个 OTP 内,则允许该 OTP,然后实现从该 OTP 计算下一个 10,以检查输入的下一个 OTP。在成功使用之前忽略窗口中未使用的任何 OTP 具有相当好的意义。

笔记:

在 HOTP 10 中是任意的。通常这个因素大约是成功验证所需的 OTP 数量的 2.5 倍。因此,如果用户需要 3 个 HOTP 来进行身份验证,则该窗口将在当前一个之后大约 8 个 OTP。

在 TOTP 5 秒内也是可变的。在某些情况下,我看到的窗口大到 100% 的移动步长。因此,以 30 秒的步长和 30 秒的窗口有效地使代码在 1:30 有效。同样,在当前迭代之前和之后扩展。

您可能还想查看 RFC6238 (TOTP)。https://www.rfc-editor.org/rfc/rfc6238#page-6

有一个用于验证 OTP 值的时间窗口。(正如@Nalaurien 指出的那样,只有一次)。允许使用较旧甚至更新的 TOTP 值也有实际原因:硬件令牌的时钟偏差以及用户需要读取和输入 OTP 值的时间。

时钟偏差和硬件

请注意,TOTP 是在 2011 年指定的。作为 TOTP 的基础的 HOTP 甚至在 2005 年就指定了。iphone 1 于 2007 年发布。TOTP 从来没有在智能手机上运行,​​而是在时钟差的廉价硬件密钥卡上运行有一个可能漂流的时间。

您可能还会注意到 HOTP (RFC4226) 和 TOTP (RFC623) 是由在身份验证硬件公司工作的人员编写的,而不是与 Google 或 Apple 合作。;-)