使用OpenSSL进行MD5 HMAC加密

6

我尝试使用OpenSSL生成MD5 HMAC,大部分代码都是借用的。但是生成的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);
  }
}

哈希值计算出现错误。我希望能得到一些反馈或者有人指点我正确的方向。
3个回答

8

HMAC的第三个和第五个参数是错误的。您需要传递密钥长度和数据长度。在您的示例中,分别为64和84,而不是32和28。

因此:

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

通过这种修改,看起来它运行良好。


-1

如果您编写以下代码,可以使 OpenSSL HMAC 命令整洁:

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

因为 keydata 都是使用字符串字面值初始化的,所以它们的最后一个字符是 \0。这个终止符不应被散列。我们通过指定数组大小减去最后一个字符来跳过此字符。

您可以从 https://www.rfc-editor.org/rfc/rfc2202 获取 HMAC-MD5 的其他测试向量。


1
如果keydata被初始化为字符串字面量,则应该是sizeof(key) - 1sizeof(data) - 1。原因是,使用字符串字面量初始化的字符数组(例如"johndoe")会附加上\0字符。因此,相应的字符数组实际上具有字符序列johndoe\0。通常不应将\0哈希进去,因为这是C/C++特定的行为。 - nuiun

-2

使用

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

而不是

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

它通常适用于任何数据密钥


如果你的代码中有这个,那么它是错误的,你可能还有其他错误。密钥是二进制数据,它可能包含空字节。在密钥上调用 strlen 是无意义的。数据可能恰好是文本,也可能不是,因此调用 strlen 可能正确,也可能不正确。 - Gilles 'SO- stop being evil'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接