C# Google验证器代码不匹配

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

我正在使用谷歌验证器进行两步验证。它在本地工作正常。在生产代码中不匹配。因为我的服务器和我的移动时区不匹配。如何将我的服务器时区与我的移动应用程序同步。我使用的是基于时间的代码

调用函数有效(secretcode、密码)

我的代码

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分钟的时间,如果我有你的话我正确地理解了代码。