C# Google验证器代码不匹配
我正在使用谷歌验证器进行两步验证。它在本地工作正常。在生产代码中不匹配。因为我的服务器和我的移动时区不匹配。如何将我的服务器时区与我的移动应用程序同步。我使用的是基于时间的代码 调用函数有效(secretcode、密码) 我的代码C# Google验证器代码不匹配,c#,android,C#,Android,我正在使用谷歌验证器进行两步验证。它在本地工作正常。在生产代码中不匹配。因为我的服务器和我的移动时区不匹配。如何将我的服务器时区与我的移动应用程序同步。我使用的是基于时间的代码 调用函数有效(secretcode、密码) 我的代码 public static class TimeBasedOneTimePassword { public static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, Date
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);
}
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)
{
string cache_key = string.Format("{0}_{1}", secret, password);
if (_cache.Contains(cache_key))
{
throw new OneTimePasswordException("You cannot use the same secret/iterationNumber combination more than once.");
}
_cache.Add(cache_key, cache_key, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(2) });
string strpass = GetPassword(secret);
if (password ==strpass )
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;
}
}
public静态类TimeBasedOneTimePassword
{
public static readonly DateTime UNIX_EPOCH=new DateTime(1970,1,1,0,0,DateTimeKind.Utc);
私有静态内存缓存;
静态TimeBasedOneTimePassword()
{
_缓存=新的MemoryCache(“TimeBasedOneTimePassword”);
}
公共静态字符串GetPassword(字符串机密)
{
返回GetPassword(secret,GetCurrentCounter());
}
公共静态字符串GetPassword(字符串机密、日期时间历元、int-timeStep)
{
长计数器=GetCurrentCounter(DateTime.UtcNow、epoch、timeStep);
返回GetPassword(密码、计数器);
}
公共静态字符串GetPassword(字符串机密、日期时间、日期时间历元、整数时间步长、整数位数)
{
长计数器=GetCurrentCounter(现在、历元、时间步);
返回GetPassword(密码、计数器、数字);
}
私有静态字符串GetPassword(字符串机密、长计数器、整数位数=6)
{
返回HashedOnItemPassword.GeneratePassword(密码、计数器、数字);
}
私有静态长GetCurrentCounter()
{
返回GetCurrentCounter(DateTime.UtcNow,UNIX\u EPOCH,30);
}
私有静态长GetCurrentCounter(现在日期时间、日期时间历元、整数时间步)
{
返回(长)(现在-历元).TotalSeconds/timeStep;
}
公共静态bool有效(字符串机密、字符串密码、int-checkAdjacenterVals=1)
{
string cache_key=string.Format(“{0}{1}”,secret,password);
if(_cache.Contains(cache_key))
{
抛出新的OneTimePasswordException(“不能多次使用同一个secret/iterationNumber组合”);
}
_Add(cache_key,cache_key,new CacheItemPolicy{SlidingExpiration=TimeSpan.FromMinutes(2)});
字符串strpass=GetPassword(secret);
如果(密码==strpass)
返回true;
对于(int i=1;我没有查看验证器API,但我希望所有时间戳都以UTC格式发送。你真的不想与其他任何时间处于同一时区。你能给我们看一下你的代码吗?是的,我只使用UTC时间。当我检查本地系统时间和移动时间不匹配时。该时间代码不起作用。在在我更改了移动时间后,它工作正常。但是我的服务器时间和我的时间相差10小时。我已更新了代码。如果您在客户端和服务器上都使用UTC,那么问题不在于时区。服务器UTC时间和您的UTC时间至少应该非常同步。您是否有指向客户端将使用的文档的链接发送?(我对30分的除法有点怀疑,尽管可能没问题…)您需要什么文档。我已经在本地和服务器中检查了UTC时间。它显示了4分钟的差异。那么这可能就是问题所在-看起来您只能处理默认情况下最多30秒的时间。如果您在调用它时为checkAdjacenterVals
指定10,那么它应该可以处理最多5分钟的时间,如果我有你的话我正确地理解了代码。