我正在我们的网站上使用Google身份验证器实施2FA。如果我理解正确,每个用户都将拥有自己的密码,登录时我需要密码验证他们输入的6位数代码。
将这些密码存储在与用户密码相同的数据库中似乎是一个坏主意(尽管如果有人掌握了数据库,我们会遇到更大的问题),那么它周围有什么问题吗?或者它们应该被视为密码并加密?
答案 0 :(得分:4)
您无法散列用于为Google身份验证器生成TOTP代码的密码,因为您需要原始密码来实际生成代码。
就像你说的那样,如果有人拥有你的数据库,那么无论如何你都会遇到更大的麻烦。然而,这是2因素身份验证应该如何工作。如果密码确实是安全的,并且攻击者只有TOTP秘密,那么他们所能做的只是生成登录所需的2个因素中的1个,他们还有更多的工作要做,以打破或窃取密码。
如果您不想担心为用户存储这些机密并让第三方处理这些机密,我建议您查看Twilio's Two Factor Authentication API。完全披露,我为Twilio工作,但如果你不想担心照顾你不能散列的秘密,以及利用Authy app等其他东西(包括秘密)没有QR码的转移)和extra device data that is now available with authentications那么它可能是有意义的。
答案 1 :(得分:0)
你是对的。
2FA确实提高了用户安全性,但从定义上讲在服务器端并不是那么强大。如果具有数据库访问权限的黑客或恶意员工转储并发布用户机密,则附加安全性将消失。
可以做什么? 您可以创建一个外部隔离的微服务,该服务接收用户哈希并生成2FA密钥,对其进行加密并存储在键值数据库中,例如elasticsearch。您可以在服务器启动后动态设置密码密钥,以免对其进行硬编码。您可以将数据库存储在员工无法通过API访问的外部服务器上。
这样,如果恶意行为者转储elasticsearch数据库,他们将不知道秘密是什么,即使他获得了加密密钥的访问权,他也不知道谁是使用该秘密的用户,因为该密钥是用户ID哈希(不是用户ID)。
没有什么是完美的,但是2FA的目标是使攻击者更难取得成功。我认为有帮助。
答案 2 :(得分:-1)
我希望这些双因素代码是有时间限制的(例如:5分钟),在我看来这是一个充分的缓解。例如,获取数据库的黑客只能在访问后很短的时间内使用这些代码。老实说,他不太可能在那段时间内获得任何用户的第一个因素(密码)(假设你没有进行密码哈希the wrong way),所以第二个因素甚至不会发挥作用场景。
(这个论点独立于6位代码的强力搜索空间非常小的点)
如果它们没有时间限制,那么您应该考虑实现自己的超时而不是散列值。对于具有长寿命的数据,散列更好。