1

我正在尝试了解Google Two Factor Authenticator流程是如何工作的,以便将其合并到我的网站中。我的理解是这个过程有两个不同的部分

  1. 我网站上的一个用户启用了 2FA,它在我的用户和应用程序之间创建了一个链接。这是一次性步骤,不会在每次登录尝试时发生。
  2. 每次用户登录时,他都需要提供来自 Google Authenticator 应用程序的六位数代码。

现在,以下代码生成 QR 图像和设置代码以启用 2FA 并将帐户链接到 Google Authenticate。

TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
string accountSecretKey = Guid.NewGuid();
var setupInfo = tfa.GenerateSetupCode("Dotnet Awesome", login.Username, accountSecretKey, 300, 300);
ViewBag.BarcodeImageUrl = setupInfo.QrCodeSetupImageUrl;
ViewBag.SetupCode = setupInfo.ManualEntryKey;

现在,对于每个请求,我都会使用以下代码对用户进行身份验证

TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
tfa.ValidateTwoFactorPIN(accountSecretKey, "Six Digit Code");

问题

在上面的代码中,accountSecretKey我必须将代码保存到我的数据库中,以便每次我想验证时都可以传递它吗?或者,accountSecretKey我在每次登录尝试时都必须重新创建的东西?如果此代码我将存储到我的数据库中,它是否也应该像密码一样加密?

4

1 回答 1

2

当我设置它时,我倾向于:

在数据库中有一个 G2FAEnabled 列,一个用于用户的 SecretKey

生成唯一的密钥并使用它为用户正在使用设置G2FA的页面生成条形码,记住它在服务器端(放在数据库中)但不要设置启用列

要求用户在将您的站点添加到身份验证器后扫描或键入他们的设备显示的代码。这证明他们的设备设置正确,他们的设备时钟是正确的等

如果他们键入的数字是正确的,请将启用的列设置为 true 并锁定内容,以便密钥现在不可更改(更改它会杀死他们的 2FA)

从那时起,用户必须为当前服务器时间和存储在服务器上的密钥提供正确的基于时间的 pin。他们的设备时钟必须与服务器保持同步。您可以通过检查例如 6 次当前时间的任一侧试图找到匹配来实现时钟漂移的容差(这意味着设备时钟可以相对于服务器时间加减 3 分钟并且仍然匹配)。

任何停用 2FA(将启用的列设置为 false)的尝试也应该需要有效的 2FA 代码,但是您的客户服务部门的替代流程(例如查看用户的护照)应该允许在不知情的情况下重置

您不必加密数据库中的密钥 - 您必须对其进行解密才能使用它,而且它不像存储明文密码之类的错误(如果您的数据库被盗,这是一个问题,因为用户重复使用密码一直如此,因此窃取您的数据库可能意味着您泄露了用户所有其他服务的密码)因为它应该是随机数据,在您的组织之外没有任何意义,因此它不会帮助黑客闯入另一个使用相同 2FA 设备的用户站点。

通常,如果有人能够窃取您的数据库,他们已经达到了可以窃取必要位来解密您存储的任何加密内容的程度,但是如果您确定您的数据库可能会被盗,但您的网络服务器会保持安全,然后通过各种方式加密数据库数据

于 2021-02-22T20:14:06.293 回答