我在这里和其他地方读过很多关于使用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是安全的,除非他/她可以物理访问计算机。我只担心数据库案例被破坏。)< / p>
也许一个想法是加密128位随机数? (需要是双向的 - 而不是哈希。)应用程序可以访问加密密钥,但是可能存储数据库凭据。
有没有人实现了我所谓的验证cookie(不是持久登录cookie)并且可以告诉我(我们)它是如何完成的?
更新:考虑到这一点,我认为足够安全的是:Cookie由userID和128位随机数组成 - 称之为R。
数据库包含密码和R,每个都经过散列和盐渍(例如,使用PhPass)。然后,R被认为是第二个密码。好处:即使第一个密码不好(例如“password1”),R也是一个非常好的密码。数据库确实无法破解,所以不应该担心。 (我想,我不必担心它。)
答案 0 :(得分:1)
我认为你在这里有一个非常好的计划。一般来说,cookie应该是完全随机的,不应包含服务器使用的任何数据。这个想法是客户控制的任何东西都可以被篡改。即使价值被加密,我也看到攻击者扭曲了比特并将篡改后的数据解密为不同用户的ID(是的,有人吓到我了)。话虽如此,我认为Charlie Miller的建议很好,因为128位是一个很好的熵量。就我个人而言,我会使用完全随机的字节来获取cookie,这样就不会出现任何模式。
我们最后一次验证cookie的实现是一个完全随机的256位值,用ascii-hex打印,映射到我们数据库中的用户ID和会话信息。我们使用密钥保存会话信息,因此如果攻击者SQL注入了我们的数据库,那么它们都将是无用的加密信息。当然,数据库机器的完全妥协将提供对密钥的访问,但这样做要困难得多,因为它涉及多个漏洞利用和支点。
一些好的建议是不要过分考虑它。我们遇到了实施问题,因为我们“过度设计”,最终我们没有获得太多的安全优势。一个简单的随机数是你能做的最好的(只要它足够长以提供足够的熵)。
答案 1 :(得分:0)
在安全堆栈交换站点(这可能是这个问题所属的地方)上有一个很好的答案: