相同输入调用不同OpenSSL evp.h接口得到不同SHA256哈希值的原因是什么?
问题原因及修复方案
问题根源
你代码中的msg_size变量在第一次调用EVP_DigestFinal_ex时被意外修改了:
EVP_DigestFinal_ex的第三个参数是输出参数,调用后会被赋值为当前哈希算法的摘要长度(SHA256对应值为32)。- 你初始把
msg_size赋值为输入字符串长度25,经过EVP_DigestFinal_ex调用后,msg_size被覆盖为32。 - 后续调用
EVP_Digest时传入的长度参数是被修改后的32,相当于会读取输入字符串后面额外7字节的栈上随机脏数据,因此得到的哈希值和预期不符。
修复方案
最简单的修复方式是将存储输入长度的变量声明为const,同时单独使用临时变量存储哈希输出长度,避免变量被意外修改,修改后的核心代码如下:
int main (int argc, char *argv[]) { EVP_MD_CTX *ctx; char *msg = (char*)"I have the high ground..."; // 将输入长度声明为const,避免被意外修改 const unsigned int msg_size = strlen(msg); unsigned char digest_a[SHA256_DIGEST_LENGTH] = {0}; unsigned char digest_b[SHA256_DIGEST_LENGTH] = {0}; // 单独定义变量存储哈希摘要的输出长度 unsigned int digest_len = 0; cout << "message: " << msg << endl; cout << "length: " << msg_size << endl; ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(ctx, EVP_sha256(), NULL); EVP_DigestUpdate(ctx, msg, msg_size); // 传入专门的digest_len变量接收输出长度 EVP_DigestFinal_ex(ctx, digest_a, &digest_len); hex_print("sha256: ", digest_a, SHA256_DIGEST_LENGTH); EVP_Digest (msg, msg_size, digest_b, NULL, EVP_sha256 (), NULL); hex_print ("sha256: ", digest_b, SHA256_DIGEST_LENGTH); EVP_MD_CTX_free(ctx); return EXIT_SUCCESS; }
修改后两次计算得到的SHA256哈希值会完全一致。
内容的提问来源于stack exchange,提问作者Siedler
相关产品推荐
相关产品推荐

