【问题标题】:MD5 HMAC With OpenSSL带有 OpenSSL 的 MD5 HMAC
【发布时间】:2012-11-13 09:43:34
【问题描述】:

我尝试使用 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);
  }
}

生成的哈希不正确。我将不胜感激一些反馈或有人指出我正确的方向。

【问题讨论】:

    标签: c openssl md5 hmac


    【解决方案1】:

    使用

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

    代替

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

    它通常适用于任何数据

    【讨论】:

    • 如果你在代码中的任何地方都有这个,那就错了,你可能还搞错了其他事情。密钥是二进制数据,它可能有空字节。在按键上调用strlen 是无稽之谈。数据可能是文本,也可能不是,因此调用strlen 可能正确也可能错误。
    【解决方案2】:

    如果你写的话,你可以让一体化的 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 测试向量。

    【讨论】:

    • 如果 keydata 用字符串初始化,则它应该是 sizeof(key) - 1sizeof(data) - 1。原因:使用 "johndoe" 等字符串字面量初始化的 char 数组附加了 \0 字符。所以对应的char数组其实有字符序列johndoe\0。通常不应将 \0 散列进去,因为这是 C/C++ 特定的行为。
    【解决方案3】:

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

    通过此修改,它似乎工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      • 2016-02-07
      • 2014-08-23
      • 1970-01-01
      相关资源
      最近更新 更多