RFC 6238建议服务器实施某种形式的重新同步算法,以解决用于生成 OTP 的设备的时间漂移。然而,RFC 几乎没有提供关于如何实际实现这种同步以及它可能对算法的整体安全性产生的影响的信息。这种时间漂移通常是无法与 NTP 同步的设备的问题,例如大多数可编程 TOTP 硬令牌。我想在这里分享我们的建议,并希望提出一种安全的算法,充分考虑设备中的时间漂移,并且最终用户需要最少的努力。我还添加了一些我在提案中看到的潜在问题。
同步算法
我们使用 30 秒的窗口,这对于 TOTP 来说是典型的,但原则应该与其他窗口大小相同。在本提案中,n 是当前验证窗口,考虑到为该设备记录的漂移校正。n-1 是前一个窗口,n+1 是下一个窗口,依此类推。延迟窗口(OTP 生成与其验证之间的时间)设置为 1 步,如 RFC 6238 所建议的那样。这解释了两者之间的差异向前和向后搜索。
- 窗口 n-2、n-1、n 和 n+1 的 OTP 被接受为有效。
- 在 n-2 和 n+1 处,设备的漂移分别以 -1 和 +1 时间步自动调整。
- 对于 n-6 和 n+5 之间的其他窗口,检测到漂移但不会自动调整。开始手动漂移校正(如下所述)。11个验证窗口的漂移检测窗口应该足以让用户在长时间不登录的情况下重新同步TOTP。
- 还会检查漂移校正为 0 的 OTP。如果此 OTP 匹配,则时间漂移本身被纠正,并开始手动漂移纠正以偏移 0(当前服务器时间)。
- 所有其他 OTP 均被拒绝。
手动漂移校正是要求用户输入 2 个连续 OTP 的过程。这些 OTP 用于计算距离系统时间最多 1 小时的偏移量。无法提供 2 个连续的 OTP 被视为登录尝试失败。
可能的问题
RFC 建议不要将窗口扩大到超过两个时间步(n 和 n-1)。该建议增加了 2 个额外的时间步长(n-2 和 n+1)用于自动调整偏移量。如果不将窗口扩大到至少 4 个步骤,我认为无法执行这种自动调整。当然,自动调整可以完全省略,但手动重新同步对于最终用户来说并不是很愉快。窗口的加宽是否足够小以在安全性和可用性之间保持良好的平衡?
将针对总共 13 个窗口检查 OTP。这可能会导致有关秘密的信息泄露。在我看来,这不是问题,因为建议的密钥长度与散列相结合将使(实际上)无法猜测密钥,尤其是在尝试速率受限的情况下。
使用 2 个连续的 OTP 是否足以可靠地确定 240 个时间步长(前后 1 小时)的窗口中的偏移量?1 小时的最大偏移量是否足以说明所用设备的时间漂移?