Authy 向我显示与服务器没有任何连接的秘密号码。它怎么能做到?
Authy 使用一次性密码 (OTP) 算法,该算法有多种形式,其中两种最流行的是基于 HMAC 的 OTP (HOTP) 和基于时间的 OTP (TOTP)。Authy 正在使用 TOTP。
两种算法本质上是相同的;他们需要一些种子数据和一个计数器来生成系列中的下一个密码。每次用户请求/使用密码时,HOTP 实现都会增加计数器,TOTP 会在给定时间间隔后增加计数器。
在 Authy 的案例中,当用户向服务器提交密码时,服务器会查找用户的种子数据,根据请求的时间戳计算计数器值,然后生成正确的密码。然后服务器检查生成的密码是否与用户提交的密码匹配。
它安全吗?如果我知道前 N 个数字,我能知道下一个数字吗?
是与否,这取决于您是否信任服务器的安全性。
给定 N 个先前的令牌,攻击者仍然不应该能够恢复种子数据。但是,这些算法需要服务器存储所有用户的种子数据。如果攻击者能够破坏数据库(通过 SQL 注入等),那么他们将能够生成有效的密码。这就是 RSA 及其 SecurID 令牌所发生的事情 ( http://arstechnica.com/security/2011/06/rsa-finally-comes-clean-securid-is-compromised/ )
Duo Security ( https://www.duosecurity.com/ ) 和 Twitter ( https://blog.twitter.com/2013/login-verification-on-twitter-for-iphone-and-android ) 等公司正在解决这些问题通过使用非对称密钥加密实现质询-响应两因素身份验证来解决这个问题。在这种情况下,他们只需要存储公钥,这意味着如果他们的数据库被泄露,攻击者就没有生成有效响应所需的私钥。
免责声明,我在 Duo 工作。
根据评论中的问题更新
服务器和客户端应用程序上的算法(HOTP 或 TOTP)必须相同吗?
算法是相同的,只是计数器值的生成方式不同。如果 Google 是 HOTP 并且 Authy 想要支持 Google 帐户,他们的应用程序必须生成和存储与 TOTP 帐户不同的计数器值。
HOTP 客户端是否需要与服务器连接才能获取下一个密码(因为它不知道上次发出了多少请求),而 TOTP 不需要它?
不,HOTP 不需要连接即可工作,但通常不使用 HOTP,因为电话和服务器很容易不同步。
假设服务器和应用程序都以计数器值 0 开始。服务器通常有一个窗口,可能是接下来的 10 个密码,它将认为是有效的。当用户提交密码时,服务器会将提交的密码与接下来生成的 10 个密码进行比较。如果 10 个匹配,服务器可以更新存储的计数器值并保持同步。
但问题是,用户可能能够在应用程序中生成太多密码而不使用它们。如果用户能够将计数器增加到超过密码窗口大小,则服务器无法再验证密码是否有效。
要详细了解如何生成 OTP 令牌,请参阅这篇内容丰富的博文。