双重因素 Google 身份验证与服务器上的代码不匹配 - ASP.Net MVC
Two Factor Google Authentication not matching the codes on the server- ASP.Net MVC
我在使用 google 身份验证器的双因素身份验证中使用以下代码。
此验证的问题在于 google 验证器代码在我的本地计算机上正确验证,但在服务器上未正确验证。
服务器时间设置为:(UTC-05:00) 东部时间(美国和加拿大)
我的系统时间设置是:(UTC-06:00) 中部时间(美国和加拿大)
在服务器上-当我尝试多次点击验证按钮时,有时验证正确有时不正确。我不确定为什么要这样做。
任何人都可以帮我 idea/suggestion 解决这个问题
public static class TimeBasedOneTimePassword
{
public static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private static MemoryCache _cache;
static TimeBasedOneTimePassword()
{
_cache = new MemoryCache("TimeBasedOneTimePassword");
}
public static string GetPassword(string secret)
{
return GetPassword(secret, GetCurrentCounter());
}
public static string GetPassword(string secret, DateTime epoch, int timeStep)
{
long counter = GetCurrentCounter(DateTime.UtcNow, epoch, timeStep);
return GetPassword(secret, counter);
}
public static string GetPassword(string secret, DateTime now, DateTime epoch, int timeStep, int digits)
{
long counter = GetCurrentCounter(now, epoch, timeStep);
return GetPassword(secret, counter, digits);
}
private static string GetPassword(string secret, long counter, int digits = 6)
{
return HashedOneTimePassword.GeneratePassword(secret, counter, digits);
}
private static long GetCurrentCounter()
{
return GetCurrentCounter(DateTime.UtcNow, UNIX_EPOCH, 30);
}
public static long GetCurrentRemaining()
{
return (long)(DateTime.UtcNow - UNIX_EPOCH).TotalSeconds % 30;
}
private static long GetCurrentCounter(DateTime now, DateTime epoch, int timeStep)
{
return (long)(now - epoch).TotalSeconds / timeStep;
}
public static bool IsValid(string secret, string password, int checkAdjacentIntervals = 1)
{
if (password == GetPassword(secret))
return true;
for (int i = 1; i <= checkAdjacentIntervals; i++)
{
if (password == GetPassword(secret, GetCurrentCounter() + i))
return true;
if (password == GetPassword(secret, GetCurrentCounter() - i))
return true;
}
return false;
}
}
我确实尝试将 checkAdjacentIntervals 设置为 5,我能够验证 google 身份验证器代码,但如前所述,它验证了过去的代码,这在我的情况下是不正确的。
所以我们通过使用 NTP 正确同步它来更正服务器的时间,然后它开始按预期工作。
我知道这是一个老问题,但它可能会帮助像我一样前来寻找答案的人。 Google 身份验证基于时间。 API 将根据时间验证过去最近生成的代码(标记它,是时间,而不是时区)。因此,如果您系统的实际时间与您生成代码的设备不同步,就会出现问题。特别是当系统时间落后于设备时间时。如果您想验证我的答案,请尝试输入一些较旧的代码(基于系统和设备之间的联系差距)。当您的系统领先于设备时,checkAdjacentIntervals 会帮助您,但当它落后时则不会。
我在使用 google 身份验证器的双因素身份验证中使用以下代码。 此验证的问题在于 google 验证器代码在我的本地计算机上正确验证,但在服务器上未正确验证。 服务器时间设置为:(UTC-05:00) 东部时间(美国和加拿大) 我的系统时间设置是:(UTC-06:00) 中部时间(美国和加拿大)
在服务器上-当我尝试多次点击验证按钮时,有时验证正确有时不正确。我不确定为什么要这样做。
任何人都可以帮我 idea/suggestion 解决这个问题
public static class TimeBasedOneTimePassword
{
public static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private static MemoryCache _cache;
static TimeBasedOneTimePassword()
{
_cache = new MemoryCache("TimeBasedOneTimePassword");
}
public static string GetPassword(string secret)
{
return GetPassword(secret, GetCurrentCounter());
}
public static string GetPassword(string secret, DateTime epoch, int timeStep)
{
long counter = GetCurrentCounter(DateTime.UtcNow, epoch, timeStep);
return GetPassword(secret, counter);
}
public static string GetPassword(string secret, DateTime now, DateTime epoch, int timeStep, int digits)
{
long counter = GetCurrentCounter(now, epoch, timeStep);
return GetPassword(secret, counter, digits);
}
private static string GetPassword(string secret, long counter, int digits = 6)
{
return HashedOneTimePassword.GeneratePassword(secret, counter, digits);
}
private static long GetCurrentCounter()
{
return GetCurrentCounter(DateTime.UtcNow, UNIX_EPOCH, 30);
}
public static long GetCurrentRemaining()
{
return (long)(DateTime.UtcNow - UNIX_EPOCH).TotalSeconds % 30;
}
private static long GetCurrentCounter(DateTime now, DateTime epoch, int timeStep)
{
return (long)(now - epoch).TotalSeconds / timeStep;
}
public static bool IsValid(string secret, string password, int checkAdjacentIntervals = 1)
{
if (password == GetPassword(secret))
return true;
for (int i = 1; i <= checkAdjacentIntervals; i++)
{
if (password == GetPassword(secret, GetCurrentCounter() + i))
return true;
if (password == GetPassword(secret, GetCurrentCounter() - i))
return true;
}
return false;
}
}
我确实尝试将 checkAdjacentIntervals 设置为 5,我能够验证 google 身份验证器代码,但如前所述,它验证了过去的代码,这在我的情况下是不正确的。
所以我们通过使用 NTP 正确同步它来更正服务器的时间,然后它开始按预期工作。
我知道这是一个老问题,但它可能会帮助像我一样前来寻找答案的人。 Google 身份验证基于时间。 API 将根据时间验证过去最近生成的代码(标记它,是时间,而不是时区)。因此,如果您系统的实际时间与您生成代码的设备不同步,就会出现问题。特别是当系统时间落后于设备时间时。如果您想验证我的答案,请尝试输入一些较旧的代码(基于系统和设备之间的联系差距)。当您的系统领先于设备时,checkAdjacentIntervals 会帮助您,但当它落后时则不会。