繁体   English   中英

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

[英]OpenSSL MD5 gives a different hash every time

我试图通过在函数中传递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;
}

问题是每次执行代码时,我都会获得相同文本的不同哈希值。

585c64a0
554454a0
5f75a4a0, etc

MD5是确定性的,不应存在这样的问题。 出现错误等原因的原因是什么? 此外,在函数中传递EVP_MD对象对我来说很重要。

编辑:

用以下代码替换最终的printf

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

我得到以下输出。

b4000000000000000100000000000000

但是,对于所有执行,这保持不变。 但我猜这个哈希是不对的。

我觉得你很亲密 我可能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;
}

然后,使用以下命令打印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;
}

您还应该添加一些错误检查。

正如注释中所述, md5_digest_process()返回一个指向一个局部变量的指针,该函数在函数退出时超出范围,当指针指向无效内存时指针悬空。

但这与您的问题无关,因为您正在打印指针指向的内存地址 ,而不是它指向的数据 因此,您的打印输出显示调用函数时本地hash变量存在的任何随机内存地址。 这就是您在输出中看到不一致值的原因。 如注释中所述,您需要取消引用指针以打印指向的数据。

如果要返回一个指向内存超出函数的内存的指针,则必须动态分配内存:

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

否则,调用者必须分配内存并将其传递给函数以填写:

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