首页 > 解决方案 > 为什么我应该调用 EVP_DigestInit 而不是直接调用哈希函数?

问题描述

SHA512的 OpenSSL 文档中,有以下建议:

应用程序应该使用更高级别的函数 EVP_DigestInit(3) 等,而不是直接调用散列函数。

这是什么原因?更安全吗?没有解释为什么我应该使用它。

我想制作 SHA512 哈希,根据这个建议,我应该使用这个哈希 EVP_* 函数而不是 SHA512_* 函数来计算。还是我理解错了?

SHA512_CTX m_context;
SHA512_Init(&m_context)
SHA512_Update(&m_context, data, size)
SHA512_Final(hash, &m_context);


auto m_context = EVP_MD_CTX_create();
EVP_DigestInit_ex(m_context, EVP_get_digestbyname("sha512"), NULL);
EVP_DigestUpdate(m_context, data, size);
EVP_DigestFinal_ex(m_context, hash, NULL);

标签: c++hashopenssl

解决方案


我问了同样的事情,这是他们的回答 https://github.com/openssl/openssl/issues/12260

出于多种原因。例如:

在某些情况下,使用低级 API 与 EVP API 相比,您会得到次优的实现。“密码”世界的一个例子(但同样的概念也适用于摘要)是低级函数 AES_encrypt。如果您调用它,您将永远无法获得可能在您的平台上可用的 AESNI 优化版本。

我们希望鼓励应用程序对所有类型的摘要/密码等使用一致的 API。这使得每个人都可以更容易地在安全建议发生变化时更新代码。例如,您提到了 MD5 摘要 API。不再推荐使用 MD5。如果您使用的是低级 API 与高级 API,那么更新代码以使用其他摘要要困难得多。展望未来,想象一些算法在其中发现了一些重大缺陷,需要从它快速迁移到其他算法。我们希望 OpenSSL 生态系统尽可能敏捷,以便能够处理这个问题。

旧的 API 在架构上不再适合 OpenSSL 3.0 的工作方式。现在,所有算法实现都由 OpenSSL 3.0 中的“提供者”提供 - 例如,我们有“默认”提供者、“fips”提供者和“旧版”提供者。低级 API 规避了所有这些,这意味着我们必须维护 2 种方式来做所有事情(实际上,当您将 ENGINE 带入图片时也有 3 种方式)。这会导致不必要的代码膨胀和复杂性......这绝对是您希望在加密库中避免的事情。理想情况下,我们会完全删除旧方法 - 但那将是一个太大的破坏性变化。


推荐阅读