是否应该对 2FA 密码进行哈希处理以进行存储?

Should 2FA secret codes be hashed for storage?

我正在努力在我们的网站上使用 Google 身份验证器实施 2FA。如果我理解正确的话,每个用户都会有自己的密码,我需要在登录时验证他们输入的 6 位密码。

将这些密码存储在与用户密码相同的数据库中似乎不是一个好主意(尽管,如果有人掌握了数据库,我们就会遇到更大的问题),有什么办法吗?还是应该将它们视为密码并加密?

您无法散列用于为 Google 身份验证器生成 TOTP 代码的秘密,因为您需要原始秘密才能实际生成代码。

正如您所说,如果有人拥有您的数据库,那么您的麻烦就更大了。然而,这就是 2 因素身份验证应该如何工作的。如果密码确实经过安全哈希处理并且攻击者只有 TOTP 秘密,那么他们所能做的就是从登录所需的 2 个因素中生成 1 个,他们还有更多工作要做才能破解或窃取密码。

如果您不想为您的用户存储这些秘密并让第三方来处理它,我可以建议您看一看 Twilio's Two Factor Authentication API. Full disclosure, I work for Twilio, but if you don't want to worry about looking after secrets that you can't hash, as well as take advantage of other things like the Authy app (including secret transfer without QR codes) and the extra device data that is now available with authentications 那么它可能会感兴趣。

你是对的。

2FA 确实提高了用户安全性,但根据定义在服务器端并没有那么强大。如果具有数据库访问权限的黑客或恶意员工转储并发布用户机密,则额外的安全性就会消失。

可以做什么? 您可以创建一个外部隔离的微服务,接收用户哈希并生成 2FA 密钥,对其进行加密并存储在 key-value 数据库中,如 elasticsearch。您可以在服务器启动后动态设置加密密钥,不存储它 hard-coded。您可以将数据库存储在外部服务器上,员工只能通过 API.

访问该服务器

这样,如果恶意行为者转储了 elasticsearch 数据库,他们就无法知道秘密是什么,即使他获得了加密密钥的访问权限,他也不知道谁是使用该秘密的用户,因为关键是用户 ID 哈希(不是用户 ID)。

没有什么是完美的,但 2FA 的目标是让攻击者更难获得成功。我觉得有帮助。