MD5 HMAC с OpenSSL

Я пытался сгенерировать MD5 HMAC с помощью OpenSSL, и большая часть кода заимствована. Генерируемый hmac неверен:

#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <syslog.h>
#include <string.h>

#include <openssl/engine.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() 
{
  unsigned char* key = (unsigned char*) "2012121220121212201212122012121220121212201212122012121220121212";
  unsigned char* data = (unsigned char*) "johndoejohndoejohndoejohndoejohndoejohndoejohndoejohndoejohndoejohndoejohndoejohndoe";
  unsigned char* expected = (unsigned char*) "abcd1d87dca34f334786307d0da4fcbd";
  unsigned char* result;
  // unsigned int result_len = 16;
  unsigned int result_len = 16;
  int i;
  static char res_hexstring[32];

  // result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL);
  result = HMAC(EVP_md5(), key, 32, data, 28, NULL, NULL);
  for (i = 0; i < result_len; i++) {
    sprintf(&(res_hexstring[i * 2]), "%02x", result[i]);
  }

  if (strcmp((char*) res_hexstring, (char*) expected) == 0) {
    printf("Test ok, result length %d\n", result_len);
  } else {
    printf("Got %s instead of %s\n", res_hexstring, expected);
  }
}

Создаваемый хэш неверен. Я был бы признателен за отзыв или кто-то, указывающий мне в правильном направлении.


person ukhan    schedule 25.11.2012    source источник


Ответы (3)


Третий и пятый параметры HMAC просто неверны. Вы должны передать длину ключа и длину данных. В вашем примере это соответственно 64 и 84, а не 32 и 28.

So :

-    result = HMAC(EVP_md5(), key, 32, data, 28, NULL, NULL);                                                                                                                                                                         
+    result = HMAC(EVP_md5(), key, 64, data, 84, NULL, NULL); 

С этой модификацией вроде работает нормально.

person Remi Gacogne    schedule 27.11.2012

Вы можете сделать универсальную команду OpenSSL HMAC более аккуратной, если напишете:

result = HMAC(EVP_md5(), key, sizeof(key)-1, data, sizeof(data)-1, NULL, NULL);

Поскольку key и data инициализируются строковыми литералами, последним символом обоих является \0. Этот завершающий символ не следует хэшировать. Мы пропускаем этот символ, указав размер массива за вычетом последнего символа.

Вы можете получить другие тестовые векторы для HMAC-MD5 по адресу https://tools.ietf.org/html/rfc2202. .

person rustyMagnet    schedule 01.01.2017
comment
это должны быть sizeof(key) - 1 и sizeof(data) - 1, если key и data инициализированы строковыми литералами. Причина: массивы символов, инициализированные строковым литералом, таким как "johndoe", добавляются с символом \0. Таким образом, соответствующий массив символов фактически имеет последовательность символов johndoe\0. Обычно \0 не следует хэшировать, потому что это специфическое поведение C/C++. - person nuiun; 24.05.2018

Использовать

result = HMAC(EVP_md5(), key, strlen(key), data, strlen(data), NULL, NULL);

Вместо

result = HMAC(EVP_md5(), key, 32, data, 28, NULL, NULL);

Обычно это работает для любых данных и ключей.

person Yogeesh H T    schedule 27.12.2018
comment
Если у вас есть это где-то в вашем коде, это неправильно, и вы, вероятно, ошиблись в других вещах. Ключ — это двоичные данные, он может содержать нулевые байты. Вызов strlen по ключу — это нонсенс. Данные могут быть текстовыми, а могут и нет, поэтому вызов strlen может быть правильным, а может и нет. - person Gilles 'SO- stop being evil'; 27.12.2018