简体   繁体   English

OpenSSL MD5每次都会提供不同的哈希值

[英]OpenSSL MD5 gives a different hash every time

I'm trying to create a certain modular code using OpenSSL's EVP API for MD5 by passing the EVP_MD object within functions as shown below. 我试图通过在函数中传递EVP_MD对象,使用OpenSSL的MD5 EVP API创建某个模块化代码,如下所示。

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

EVP_MD* md5_digest_init() {
  OpenSSL_add_all_digests();
  EVP_MD *md = EVP_get_digestbyname("MD5");
  if(!md) {
     printf("Unable to init MD5 digest\n");
     exit(1);
   }
  return md;
}

unsigned char *md5_digest_process(EVP_MD* md, unsigned char *input_text) {
    EVP_MD_CTX mdctx;
    unsigned char hash[EVP_MAX_MD_SIZE];
    int hash_len;
    EVP_MD_CTX_init(&mdctx);
    EVP_DigestInit_ex(&mdctx, md, NULL);
    EVP_DigestUpdate(&mdctx, input_text, strlen(input_text)+1);
    EVP_DigestFinal_ex(&mdctx, hash, &hash_len);
    EVP_MD_CTX_cleanup(&mdctx);
    return hash;
}

int main() {
  EVP_MD *md;
  md = md5_digest_init();
  unsigned char* res;
  res = md5_digest_process(md, "foobar");
  printf("%02x", res);
  return 0;
}

The problem is that on executing the code every time, I obtain a different hash value for the same text. 问题是每次执行代码时,我都会获得相同文本的不同哈希值。

Such as

585c64a0
554454a0
5f75a4a0, etc

MD5 is deterministic and such an issue should not exist. MD5是确定性的,不应存在这样的问题。 Any reason why such as error exists? 出现错误等原因的原因是什么? Also, the passing of the EVP_MD object within functions is important to me. 此外,在函数中传递EVP_MD对象对我来说很重要。

EDIT: 编辑:

Replacing the final printf with the following code 用以下代码替换最终的printf

for(int i = 0; i < 16; ++i)
    printf("%02x", res[i]);

I get the following output. 我得到以下输出。

b4000000000000000100000000000000

However, this stays the same for all executions. 但是,对于所有执行,这保持不变。 But I'm guessing that this hash isn't right. 但我猜这个哈希是不对的。

I think you are close. 我觉得你很亲密 I would probably change md5_digest_process to: 我可能md5_digest_process更改为:

/* md_digest is declared as unsigned char md_digest[EVP_MAX_MD_SIZE] */
unsigned int md5_digest_process(EVP_MD* md, unsigned char *input_text, unsigned int input_len, unsigned char* md_digest)
{
    int hash_len;
    EVP_MD_CTX mdctx;

    EVP_MD_CTX_init(&mdctx);
    EVP_DigestInit_ex(&mdctx, md, NULL);
    EVP_DigestUpdate(&mdctx, input_text, input_len);
    EVP_DigestFinal_ex(&mdctx, md_digest, &hash_len);
    EVP_MD_CTX_cleanup(&mdctx);
    return hash_len;
}

Then, print md_digest with: 然后,使用以下命令打印md_digest

int main()
{
  EVP_MD *md;
  unsigned char hash[EVP_MAX_MD_SIZE];
  unsigned int hash_len;

  md = md5_digest_init();
  hash_len = md5_digest_process(md, "foobar", 6, hash);

  for(unsigned int i=0; i<hash_len; i++)
      printf("%02x", hash[i]);
  printf("\n");

  return 0;
}

You should also add some error checking. 您还应该添加一些错误检查。

As stated in comments, md5_digest_process() is returning a pointer to a local variable that goes out of scope when the function exits, leaving the pointer dangling as it is left pointing to invalid memory. 正如注释中所述, md5_digest_process()返回一个指向一个局部变量的指针,该函数在函数退出时超出范围,当指针指向无效内存时指针悬空。

But that doesn't matter to your issue, because you are printing the memory address that the pointer is pointing at, not the data that it is pointing at. 但这与您的问题无关,因为您正在打印指针指向的内存地址 ,而不是它指向的数据 So your printed output is displaying whatever random memory address the local hash variable existed at when the function was called. 因此,您的打印输出显示调用函数时本地hash变量存在的任何随机内存地址。 That is why you are seeing inconsistent values in your output. 这就是您在输出中看到不一致值的原因。 As stated in comments, you need to dereference the pointer in order to print the data that is being pointed at. 如注释中所述,您需要取消引用指针以打印指向的数据。

If you want to return a pointer to memory that outlives the function, you have to allocate the memory dynamically: 如果要返回一个指向内存超出函数的内存的指针,则必须动态分配内存:

unsigned char* md5_digest_process(EVP_MD* md, unsigned char *input_text, int *hash_len) {
    unsigned char *hash = (unsigned char *) malloc(EVP_MAX_MD_SIZE);
    if (!hash) return NULL;
    EVP_MD_CTX mdctx;
    EVP_MD_CTX_init(&mdctx);
    EVP_DigestInit_ex(&mdctx, md, NULL);
    EVP_DigestUpdate(&mdctx, input_text, strlen(input_text)+1);
    EVP_DigestFinal_ex(&mdctx, hash, hash_len);
    EVP_MD_CTX_cleanup(&mdctx);
    return hash;
}

int main() {
  EVP_MD *md = md5_digest_init();
  int hash_len = 0;
  unsigned char* res = md5_digest_process(md, "foobar", &hash_len);
  if (res) {
    for(int i = 0; i < hash_len; ++i) {
      printf("%02x", res[i]);
    }
    free(res)
  }
  return 0;
}

Otherwise, the caller will have to allocate the memory and pass it into the function to fill in: 否则,调用者必须分配内存并将其传递给函数以填写:

int md5_digest_process(EVP_MD* md, unsigned char *input_text, unsigned char* hash) {
    EVP_MD_CTX mdctx;
    int hash_len = 0;
    EVP_MD_CTX_init(&mdctx);
    EVP_DigestInit_ex(&mdctx, md, NULL);
    EVP_DigestUpdate(&mdctx, input_text, strlen(input_text)+1);
    EVP_DigestFinal_ex(&mdctx, hash, &hash_len);
    EVP_MD_CTX_cleanup(&mdctx);
    return hash_len;
}

int main() {
  EVP_MD *md = md5_digest_init();
  unsigned char hash[EVP_MAX_MD_SIZE];
  int hash_len = md5_digest_process(md, "foobar", hash);
  for(int i = 0; i < hash_len; ++i) {
    printf("%02x", res[i]);
  }
  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM