2017-10-06 6 views
0

J'ai écrit la fonction suivante pour générer HMAC-SHA1 référence https://tools.ietf.org/html/rfc2104, cependant, les valeurs que je génère semblent différer des valeurs données sur https://tools.ietf.org/html/rfc2202 et de ce que j'ai testé sur https://www.freeformatter.com/hmac-generator.html. Par exemple, la fonction doit générer de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 pour le texte "Le renard brun rapide saute par-dessus le chien paresseux" avec la touche "clé", mais il génère à la place.Fonction HMAC auto-écrit, ne fonctionne pas correctement

Quelqu'un pourrait-il signaler mes erreurs?

La fonction:

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; 
} 

edit: Dans la ligne

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

'0' devrait être 0 à la place: int au lieu de char. Merci à @Igor Tandetnik pour cela.

+0

Ce que tu fais juste pour l'éducation, ou voulez-vous réellement utiliser votre fonction HMAC quelque part? Parce que si c'est le dernier, vous devriez vraiment trouver une bibliothèque pour le faire pour vous. De toute façon, êtes-vous sûr que la classe 'SHA1' fonctionne correctement? –

+0

Juste pour l'éducation. J'ai testé le SHA1 avec différentes valeurs par rapport aux outils en ligne et cela fonctionne bien. J'ai même mis en place des points d'arrêt et testé les valeurs et leurs valeurs SHA1 et tout semblait correct. C'est pourquoi je suis perplexe en ce moment. – Magnus

+2

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

Répondre

0

Ok..pour un peu regarder autour de moi conduire à HMAC produces wrong results. Il s'avère que je faisais la même erreur en utilisant hexa comme ascii.

J'ai utilisé une fonction pour convertir le inner_hash d'hex en ascii et tout s'est avéré parfait.

La version finale de la fonction:

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; 
} 

fonction hex_to_string prise de https://stackoverflow.com/a/16125797/3818617