2017-10-06 103 views
0

我寫了下面的函數來生成HMAC-SHA1指https://tools.ietf.org/html/rfc2104,不過,我產生了價值觀似乎從https://tools.ietf.org/html/rfc2202並從我上https://www.freeformatter.com/hmac-generator.html測試給出的值不同。自寫HMAC功能,工作不正常

例如,該函數應該生成de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9文本「快速棕色狐狸用鑰匙」鍵跳過「懶狗」,但它會生成d3c446dbd70f5db3693f63f96a5931d49eaa5bab來代替。

有人能指出我的錯誤嗎?

功能:

const int block_size = 64; 
const int hash_output_size = 20; 
const int ipadVal = 0x36; 
const int opadVal = 0x5C; 
std::string HMAC::getHMAC(const std::string &text) 
{ 
// check if key length is block_size 
// else, append 0x00 till the length of new key is block_size 
int key_length = key.length(); 
std::string newkey = key; 
if (key_length < block_size) 
{ 
    int appended_zeros = block_size - key_length; 
    // create new string with appended_zeros number of zeros 
    std::string zeros = std::string(appended_zeros, '0'); 
    newkey = key + zeros; 
} 
if (key_length > block_size) 
{ 
    SHA1 sha1; 
    newkey = sha1(key); 
} 

// calculate hash of newkey XOR ipad and newkey XOR opad 
std::string keyXipad = newkey; 
std::string keyXopad = newkey; 
for (int i = 0; i < 64; i++) 
{ 
    keyXipad[i] ^= ipadVal; 
    keyXopad[i] ^= opadVal; 
} 

// get first hash, hash of keyXipad+text 
std::string inner_hash = getSHA1(keyXipad + text); 

// get outer hash, hash of keyXopad+inner_hash 
std::string outer_hash = getSHA1(keyXopad + inner_hash); 

// return outer_hash 
return outer_hash; 
} 

編輯:在線路

std::string zeros = std::string(appended_zeros, '0'); 

'0' 應該是0,而不是:int,而不是的炭。感謝@Igor Tandetnik。

+0

採取你只是爲了教育這樣做,或者你想實際使用HMAC功能的地方?因爲如果是後者,你應該找一個圖書館爲你做。無論哪種方式,你確定'SHA1'類能正常工作嗎? –

+0

只供教育。我已經用各種值對照在線工具測試了SHA1,它運行良好。我甚至設置了斷點並測試了值和它們的SHA1值,看起來都是正確的。這就是爲什麼我現在很困惑。 – Magnus

+2

''0'!= 0' .... –

回答

0

好吧..所以有點看看我帶到HMAC produces wrong results。事實證明,我使用hex和ascii一樣犯了同樣的錯誤。

我用一個函數將inner_hash從十六進制轉換爲ascii,然後一切變得完美。

功能的最終版本:

std::string HMAC::getHMAC(const std::string &text) 
{ 
// check if key length is block_size 
// else, append 0x00 till the length of new key is block_size 
int key_length = key.length(); 
std::string newkey = key; 
if (key_length < block_size) 
{ 
    int appended_zeros = block_size - key_length; 
    // create new string with appended_zeros number of zeros 
    std::cout << "\nAppending " << appended_zeros << " 0s to key"; 
    std::string zeros = std::string(appended_zeros, 0); 
    newkey = key + zeros; 
} 
if (key_length > block_size) 
{ 
    SHA1 sha1; 
    newkey = sha1(key); 
} 

// calculate hash of newkey XOR ipad and newkey XOR opad 
std::string keyXipad = newkey; 
std::string keyXopad = newkey; 
for (int i = 0; i < 64; i++) 
{ 
    keyXipad[i] ^= ipadVal; 
    keyXopad[i] ^= opadVal; 
} 

// get first hash, hash of keyXipad+text 
std::string toInnerHash = keyXipad + text; 
std::string inner_hash = getHash(toInnerHash); 

// get outer hash, hash of keyXopad+inner_hash 
std::string toOuterHash = keyXopad + hex_to_string(inner_hash); 
std::string outer_hash = getHash(toOuterHash); 

// return outer_hash 
return outer_hash; 
} 

hex_to_string功能從https://stackoverflow.com/a/16125797/3818617