我正在尝试在 C++ 中实现 google Authenticator 机制。我总是得到与谷歌身份验证器不同的 OTP。
我想知道为什么 ?
1 - 我搜索并发现谷歌使用 HMAC-SHA1 算法。但我很怀疑,因为:
- 我读过的几乎所有文章都是旧的。似乎无关紧要。
- 我发现谷歌身份验证器代码在开源之前现在是私有的。所以恐怕谷歌可能会改变使用的算法
- 我发现 SHA1 不再安全。有些人设法使SHA1-collision。如果谷歌仍然使用它而不是其他更安全的算法,如 SHA256、SHA512,我会感到惊讶。
如果您对此有任何信息,请通知我。
2 - 我确定我的代码是正确的。
因为我将输出的哈希值与本网站中自动生成的哈希值进行了比较,它们总是匹配的。网站:https ://www.liavaag.org/English/SHA-Generator/HMAC/
因为代码很简单!
这是代码:
/*****************************************************************************************/
#include <iostream>
#include <cmath>
#include <ctime>
#include <stdio.h>
#include <string>
#include "SHA1.h"
#include "HMAC_SHA1.h"
using namespace std;
void IntegerToString(time_t epochTime, BYTE timeAsString[] , int length);
int TimeLength(time_t epochTime);
int main(void)
{
CHMAC_SHA1 sha1;
int one,two,three,four;
time_t result = time(nullptr);
result = (long long)floor(result/30);
cout << result <<endl;
int offset;
int truncatedHash;
int finalOTP;
BYTE key[33] = "atoqb4y572clkhj2sls5h72a76cnyzpe";
int key_len = 33; /*32 + null terminator*/
int text_len = TimeLength(result);
//cout << text_len << endl;
BYTE text[text_len+1];
IntegerToString(result , text , text_len);
text[text_len] = '\0';
//printf("%s",text);
/*the digest is always 20 bytes long*/
BYTE digest[20] = {0};
sha1.HMAC_SHA1(text,text_len,key,key_len-1,digest);
printf("0x");
for(int i = 0 ; i < 20 ; i++)
{
printf("%x",(int)digest[i]);
}
offset = digest[19] & 0xf;
one = (digest[offset+0] & 0x7f) << 24;
two = (digest[offset+1] & 0xff) << 16;
three = (digest[offset+2] & 0xff) << 8;
four = (digest[offset+3] & 0xff);
truncatedHash = one | two | three | four;
finalOTP = (truncatedHash % (1000000));
cout << "\nyour OTP : " << finalOTP << endl;
return 0;
}
void IntegerToString(time_t epochTime, BYTE timeAsString[] , int length)
{
time_t reverse = 1; /*to hold zeros*/
int i = 0;
while(epochTime >= 1) /*reverse : 1000 -> 10001*/
{
reverse = reverse*10+epochTime%10;
epochTime = epochTime / 10;
//cout << epochTime << "*" << reverse <<endl;
}
while(reverse != 1)
{
timeAsString[i] = (reverse%10 +'0');
reverse = reverse / 10;
//cout << i << timeAsString[i] << "#" << reverse << endl;
i++;
}
}
int TimeLength(time_t epochTime)
{
int counter = 0;
while(epochTime)
{
epochTime = epochTime / 10;
counter++;
}
return counter;
}
请帮忙。