9

我在这里和其他地方读过很多关于使用 cookie 来实现“记住我”选项的内容,但我正在寻找一种设计 cookie 来记录双因素身份验证成功的方法。例如,Google 就是这样做的:如果第二步成功(例如,您输入了通过 SMS 收到的代码),那么它会设置一个在一段时间内(例如 30 天)有效的 cookie,这意味着第二步可以绕过。将此称为“验证 cookie”。我的理解是,如果在那个时候你注销然后再登录,它不会做第二步,而只会做第一步。(我对此进行了测试,似乎就是这样。)

我的问题是如何设计这个 cookie。一种想法是将用户 ID 和 128 位随机数放入 cookie,然后将该数字与用户 ID 一起存储在数据库中。这是 Charles Miller 对持久登录 cookie 的建议 ( http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/ )。

但是,我认为这还不够好。问题在于,由于用户使用的是双因素授权,因此无论使用什么 cookie 来记录第二步成功,都应该比使用单因素授权的情况更安全。

我要避免的是:破解者拥有来自数据库的散列/加盐密码,并且以某种方式获得了密码。如果他/她有那么多,我假设验证 cookie 中的 128 位随机数也是可用的。(如果破解者通过其他方式获得了密码,并且没有数据库,那么验证 cookie 是安全的,除非他/她可以物理访问计算机。我只担心数据库被泄露的情况。)

也许一个想法是加密 128 位随机数?(需要是双向的——而不是散列。)应用程序可以访问加密密钥,可能会存储数据库凭据。

有没有人实现了我所说的验证 cookie(不是持久登录 cookie)并且可以告诉我(我们)它是如何完成的?


更新:考虑到这一点,我认为足够安全的是:Cookie 由用户 ID 和 128 位随机数组成——称之为 R。

数据库包含密码和 R,每个都经过哈希处理和加盐处理(例如,使用 PhPass)。然后R被认为是第二个密码。好处:即使第一个密码是错误的(例如,“password1”),R 也是一个非常好的密码。数据库确实不能破解,所以不用担心。(我认为我不必要地担心它。)

4

2 回答 2

2

我认为你在这里有一个很好的计划。一般来说,cookie 应该是完全随机的,并且不应包含服务器使用的任何数据。这个想法是任何受客户控制的东西都可以被篡改。即使值被加密,我也看到攻击者旋转比特并获取篡改的数据以解密为不同用户的 ID(是的,那个让我有点害怕)。话虽如此,我认为查理米勒的建议很好,因为 128 位是一个很好的熵。就我个人而言,我会为 cookie 使用完全随机的字节,这样就不会出现任何模式。

我们最后实现的验证 cookie 是一个完全随机的 256 位值,以 ascii-hex 打印,映射到我们数据库中的用户 ID 和会话信息。我们使用密钥对会话信息进行了加密,因此如果攻击者 SQL 注入了我们的数据库,这将是无用的加密信息。当然,数据库机器的全面妥协将提供对密钥的访问,但这样做要困难得多,因为它涉及多个漏洞利用和枢轴。

一些好的建议是不要想太多。我们遇到了实施问题,因为我们“过度设计”,最终我们并没有获得太多的安全优势。一个简单的随机数是你能做的最好的(只要它足够长以提供足够的熵)。

于 2013-05-24T03:08:02.650 回答
2

在 security stackexchange 站点上有一个很好的答案(这可能是这个问题所在的地方,无论如何):

https://security.stackexchange.com/questions/31327/how-to-remember-a-trusted-machine-using-two-factor-authentication-like-googles

于 2015-05-26T15:42:02.630 回答