OpenSSL MD5 每次都会给出不同的哈希值
OpenSSL MD5 gives a different hash every time
我正在尝试使用 OpenSSL 的 EVP API for MD5 创建特定的模块化代码,方法是在函数中传递 EVP_MD
对象,如下所示。
#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()
正在 return 指向局部变量的指针,该指针在函数退出时超出范围,使指针悬空,因为它指向无效内存.
但这对您的问题无关紧要,因为您打印的是指针指向的内存地址,而不是数据[=24] =] 它所指向的。因此,您的打印输出显示调用函数时本地 hash
变量存在的任何随机内存地址。这就是为什么您在输出中看到不一致的值。如评论中所述,您需要取消引用指针才能打印指向的数据。
如果你想return一个指向内存的指针,它比函数还长,你必须动态分配内存:
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;
}
我正在尝试使用 OpenSSL 的 EVP API for MD5 创建特定的模块化代码,方法是在函数中传递 EVP_MD
对象,如下所示。
#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()
正在 return 指向局部变量的指针,该指针在函数退出时超出范围,使指针悬空,因为它指向无效内存.
但这对您的问题无关紧要,因为您打印的是指针指向的内存地址,而不是数据[=24] =] 它所指向的。因此,您的打印输出显示调用函数时本地 hash
变量存在的任何随机内存地址。这就是为什么您在输出中看到不一致的值。如评论中所述,您需要取消引用指针才能打印指向的数据。
如果你想return一个指向内存的指针,它比函数还长,你必须动态分配内存:
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;
}