RubyGem ROTP 在到期间隔之前到期

问题描述

我正在构建一个 OTP 并实现了 ROTP gem。然而,ROTP 的行为并不是我所期望的。

例如,请求间隔 30 秒的 ROTP 时

at 15:00:14,this will return you an OTP say 212321
at 15:00:30,however,this will return you a new OTP say 312932

注意它是如何没有达到 30 秒的到期时间但已经返回一个新的 otp

我对基于时间的 OTP 的预期行为是

at 15:00:14,will still return 212321
at 15:00:44,will return a new OTP because it has reached the 30 secs of expiry interval

如何实现基于时间的 OTP 的预期行为?

解决方法

生成的一次性密码在令牌中没有内置过期时间。即:TOTP算法保证在某个固定的时间范围内,产生相同的令牌。

在您的情况下,212321 令牌的有效期为 15:00:00 至 15:00:29,无论您在此时间范围内何时生成它。在 15:00:30,一个新的时间段开始,您生成的令牌将是 312932,并保持该值直到 15:00:59。这是 RFC 6238 中定义的 TOTP 算法所固有的。

此行为很重要,因为服务器检查令牌的有效性将使用完全相同的算法为当前时隙生成令牌,并将其与客户端给出的令牌进行比较。根据客户端提供令牌的确切时间,您有更多或更少的回旋余地。

为了允许一些时钟漂移并提供稍微更好的可用性,rotp gem 验证器组件有一个 drift_behind 值选项,以在一段时间内仍然允许技术上过期的令牌。有关详细信息,请参阅 https://github.com/mdp/rotp#verifying-a-time-based-otp-with-drift