您所描述的(RSA 的 SecureID)基于TOTP algorithm。
您描述的不仅是时序问题,而且您还应该记住,并非所有时钟都以相同的速度运行。客户端的时钟可能比您的服务器时钟运行得稍快或稍慢,并且随着时间的推移,它们可能会变得不同步几分钟。TOTP 算法处理这个问题的方式(参见 RFC 的第 6 节)是让服务器验证它从客户端接收的代码,不仅针对当前时间代码,还针对未来的几个代码和过去的几个代码。
Client Server
Time Code Code Time Offset
Match 849207 8:30:00 -0:00
641239 8:30:30 -0:00
761548 8:31:00 -0:00
Current client time 8:30:00 849207 103970 8:31:30 -0:00 Current server time
846541 8:32:00 -0:00
861321 8:32:30 -0:00
132465 8:33:00 -0:00
如果服务器检测到代码不同步一定量,它会计算偏移量(时钟不同步的时间),然后在将来考虑该偏移量。
Client Server
Time Code Code Time Offset
628484 8:45:00 -1:30
137864 8:45:30 -1:30
679913 8:46:00 -1:30
Current client time 8:45:00 264951 Match 264951 8:46:30 -1:30 Current server time
971034 8:47:00 -1:30
626378 8:47:30 -1:30
599171 8:48:00 -1:30
即使时钟继续分开,当代码变得太不同步时,服务器也会通过增加偏移量来重新同步。
如果您确实继续这样做,我强烈建议您使用符合 RFC 的库。大多数语言都有相对容易找到的开源实现,这将使您的消费者更容易集成此身份验证。有几个 C# 实现,这个声称可以与 Google 身份验证器一起使用(我知道它符合 TOTP RFC)。
注意:大多数 TOTP 库不会为您处理重新同步过程,因为您需要存储同步偏移量。不过,这对您自己构建相当简单,只需通读 RFC 的相关部分,以便您彻底了解该过程。
附言
如果您打算将其用于机器对机器的身份验证,我会敦促您考虑它是否真的值得。虽然实现起来相当容易,但它仍然比直接的用户名和密码要多得多,而且它可能不会增加太多(如果有的话)真正的安全性(如果你没有使用 SSL,那么我会说不然。 )
类似 TOTP 的系统在共享密钥 ( code=TOTP(key, time)
) 上运行。这对人类很有用,因为攻击者无法在没有物理访问 SecureID(或任何品牌)令牌的情况下窃取代码或共享机密。唯一的攻击是从用户那里获取当前代码并立即使用它。但是,对于机器对机器的身份验证而言,情况并非如此,因为客户端机器必须有权访问共享密钥才能生成代码。如果管理员或攻击者可以从客户端系统窃取静态密码,那么他们没有理由不能窃取共享密钥。
我认为,在大多数情况下,类似 TOTP 的身份验证添加到机器-机器通信的唯一一件事就是一层晦涩难懂。只是我的两分钱。