2015-01-25 4 views
0

Я пытаюсь реализовать HMAC через sha256, но мой вывод отличается от примеров из Википедии.C HMAC Проверка выходных данных

Ожидаемый результат:

0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 

Фактический выход:

0x18615993cb350238e00f3c9858befb04160c85b8b05d797486cc47d0d864c04b 

Код:

#include <openssl/conf.h> 
#include <openssl/evp.h> 
#include <openssl/err.h> 

#include <string.h> 

unsigned char *hash(unsigned char *input, unsigned int in_len, unsigned int *out_len); 
unsigned char *hmac(unsigned char *key, unsigned int key_len, 
     unsigned char *data, unsigned int data_len, 
     unsigned char *output, unsigned int *out_len); 
void debug(unsigned char *in, unsigned int len); 

int main(int argc, char **argv) 
{ 
     unsigned int asdf; 

     unsigned char *h = hmac("key", 3, "The quick brown fox jumps over the lazy dog", 
       strlen("The quick brown fox jumps over the lazy dog"), 
       NULL, NULL); 
} 

void debug(unsigned char *in, unsigned int len) 
{ 
     int i; 

     for(i=0;i<len;i++) { 

       printf("%02x", in[i]); 

     } 

     printf("\n"); 
} 

unsigned char *hmac(unsigned char *key, unsigned int key_len, 
     unsigned char *data, unsigned int data_len, 
     unsigned char *output, unsigned int *out_len) 
{ 
     #define BLOCK_SIZE 32 

     int i, nkey, o_len; 
     char i_pad[BLOCK_SIZE], o_pad[BLOCK_SIZE]; 

     /* Key init */ 

     if(key_len > BLOCK_SIZE) 
       key = hash(key, key_len, &nkey); 
     else if(key_len < BLOCK_SIZE) { 
       // zero pad to the right 
       char *n_key = malloc(BLOCK_SIZE); 
       memset(n_key, '\0', BLOCK_SIZE); 
       memcpy(n_key, key, key_len); 
       key = n_key; 
     } 

     printf("key:\n"); 
     debug(key, BLOCK_SIZE); 

     /* Padding init */ 

     for(i=0;i<BLOCK_SIZE;i++) { 
       o_pad[i] = key[i]^0x5c; 
       i_pad[i] = key[i]^0x36; 
     } 

     printf("o_pad:\n"); 
     debug(o_pad, BLOCK_SIZE); 

     printf("i_pad:\n"); 
     debug(i_pad, BLOCK_SIZE); 

     /* Stage 1: calculate hash(i_pad . data)*/ 

     unsigned char *stg1 = malloc(BLOCK_SIZE+data_len); 
     memcpy(stg1, i_pad, BLOCK_SIZE); 
     memcpy(stg1+BLOCK_SIZE, data, data_len); 

     printf("stg1 input:\n"); debug(stg1, BLOCK_SIZE+data_len); 
     stg1 = hash(stg1, BLOCK_SIZE+data_len, &o_len); 
     printf("stg1 hashed:\n"); debug(stg1, BLOCK_SIZE); 

     /* Stage 2: calculate hash(o_pad . stg1) */ 

     unsigned char *stg2 = malloc(BLOCK_SIZE+o_len); 
     memcpy(stg2, o_pad, BLOCK_SIZE); 
     memcpy(stg2+BLOCK_SIZE, stg1, o_len); 

     printf("stg2 input:\n"); debug(stg2, BLOCK_SIZE+o_len); 
     stg2 = hash(stg2, BLOCK_SIZE*2+data_len, &o_len); 
     printf("stg2 hashed:\n"); debug(stg2, BLOCK_SIZE); 

} 

unsigned char *hash(unsigned char *input, unsigned int in_len, unsigned int *out_len) 
{ 
     EVP_MD_CTX ctx; 
     int i; 
     unsigned char *ret = malloc(EVP_MAX_MD_SIZE); 

     EVP_MD_CTX_init(&ctx); 
     EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL); 

     EVP_DigestUpdate(&ctx, input, in_len); 
     EVP_DigestFinal_ex(&ctx, ret, out_len); 
     EVP_MD_CTX_cleanup(&ctx); 

     return ret; 
} 

Можно ли обнаружить какие-либо очевидные недостатки? Благодарю.

+1

Просто, чтобы быть уверенным: вы знаете, что есть 'openssl' функция' HMAC', которые вы можете использовать для этого? https://www.openssl.org/docs/crypto/hmac.html –

+0

согласен, гораздо читаем. Весь этот код выше в одной строке: HMAC (EVP_sha256(), key, strlen (key), (unsigned char *) данные, strlen (данные), NULL, NULL) –

ответ

0

Вы делаете все правильно с помощью stg1, но на последнем этапе вы должны сделать EVP_DigestUpdate дважды вместо memcpy.

39c39 
<   #define BLOCK_SIZE 32 
--- 
>   #define BLOCK_SIZE 64 
85,90d84 
<   memcpy(stg2, o_pad, BLOCK_SIZE); 
<   memcpy(stg2+BLOCK_SIZE, stg1, o_len); 
< 
<   printf("stg2 input:\n"); debug(stg2, BLOCK_SIZE+o_len); 
<   stg2 = hash(stg2, BLOCK_SIZE*2+data_len, &o_len); 
<   printf("stg2 hashed:\n"); debug(stg2, BLOCK_SIZE); 
91a86,96 
>   EVP_MD_CTX ctx; 
>   EVP_MD_CTX_init(&ctx); 
>   EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL); 
>   EVP_DigestUpdate(&ctx, o_pad, BLOCK_SIZE); 
>   EVP_DigestUpdate(&ctx, stg1, o_len); 
>   EVP_DigestFinal_ex(&ctx, stg2, &o_len); 
>   EVP_MD_CTX_cleanup(&ctx); 
> 
>   printf("output:\n"); 
>   debug(stg2, o_len); 
>   return stg2; 

выход:

f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

Смежные вопросы