[英]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.