用C#写谷歌身份验证的时候,手机口令校验无法通过。私钥用的都是一样的。算法是
HOTP(K,C) = Truncate(HMAC-SHA-1(K,C)) 用的时间戳。代码如下:
#region GenerateCode 生成验证码
public string GenerateCode(string accountSecretKey)
{
DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
TimeSpan ts = DateTime.UtcNow - _epoch;
long minuteValue = (long)(ts.TotalSeconds / 30);
byte[] key = Encoding.UTF8.GetBytes(accountSecretKey);
return GenerateHashedCode(key, minuteValue);
}
internal string GenerateHashedCode(byte[] key, long thisTime)
{
byte[] counter = BitConverter.GetBytes(thisTime);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(counter);
}
HMACSHA1 hmac = new HMACSHA1(key, true);
//HMACSHA1 hmac = GetHMACSha1Algorithm(key);
byte[] hash = hmac.ComputeHash(counter);
int offset = hash[hash.Length - 1] & 0xf;
// 获取4个字节组成一个整数,其中第一个字节最高位为符号位,不获取,使用0x7f
// Convert the 4 bytes into an integer, ignoring the sign.
int binary =
((hash[offset] & 0x7f) << 24)
| (hash[offset + 1] << 16)
| (hash[offset + 2] << 8)
| (hash[offset + 3]);
int password = binary % (int)Math.Pow(10, 6);
return password.ToString(new string('0', 6));
}
#endregion
麻烦大神帮忙看看,是哪里的问题?
弄了半天,算法没有问题。原来是因为客户端和服务器端的Key不一样,服务器端生成的Key是要对客户端的Key进行Base32编码后的值。
您好,能否麻烦给我发个demo,我邮箱:289094675@qq.com,谢谢
你好,能否麻烦给个demo吗?我转码应该有点问题
https://github.com/search?utf8=%E2%9C%93&q=Google+Authenticator&type=
参考这试试 选择你熟悉的语言。 手机输入的是key编码后的,服务端验证的是原始的key 比如:key=12345 手机的口令需要对12345进行编码。服务端验证直接传12345过去
@jiaojialin7991: 哇,原来如此,昨天试了很多都以为是手机端输入源码,服务端输入转码,搞错了,谢谢大神指点,我用的你的算法,测试可行,太感谢了。
@EasyAuthor: 不客气