我试图找出 C 中是否有任何用于计算 64 位哈希的 API。我发现有些人使用 MD5/SHA1 等的前 64 位。这是一个好方法吗?
6 回答
您可以尝试将 SipHash作为 MAC 的形式(不过这需要密钥管理)。它特别适合短输入消息并针对加密强度。AC实施也是可用的。
但是,如果您真的很在意有人主动弄乱您的文件,那么您不应该将自己限制为 64 位安全性。如果有足够的时间和资源,今天即使是蛮力也可以破解 64 位。为此,您应该使用 SHA-256 或更高版本。或者让我反过来说,将损坏的选项列入黑名单:不要使用 MD5(或 MD-anything)。仅当由于某种原因不能使用 SHA-256 时才使用 SHA-1。
使用散列还有一个优点,即您不需要管理任何密钥(与使用 MAC 相反)。您应该将计算的哈希值保存在与您将要监视的文件不同的位置 - 否则篡改您的文件的人也很容易篡改校验和。
关于截断哈希是好是坏
从理论上讲,我不明白为什么将 160 位哈希值截断为 64 位是错误的,无论您是采用最高有效位还是最低有效位,还是使用任意模式选择它们。我能想到的为什么不经常这样做的唯一原因是效率 - 如果有更有效的算法来处理较小的问题,为什么还要带大枪。
在下文中,我假设为此目的使用加密安全哈希,通用哈希是一个完全不同的主题 - 据我所知,它们可能会在截断时暴露攻击面。
但是,对于加密安全的哈希,除非算法被破坏,否则我们可以假设它的输出与均匀分布的随机变量的输出没有区别。
如果我们现在截断这个值,我们不会对算法的内部工作提供任何进一步的了解。尽管如此,我们确实通过一个简单的事实削弱了安全性,即根据概率法则,暴力破解(无论是碰撞还是寻找原像)现在花费的时间更少。
例如,查找 64 位哈希的冲突平均需要大约 2^32 次尝试 - 生日悖论说。如果您将输出截断为原始 64 位哈希的最低有效 32 位,那么您将在大约 2^16 的时间内发现冲突,因为您只需忽略最高有效 32 位,而事实上的均匀分布会完成其余的工作- 就像您首先开始搜索具有 32 位值的冲突。
这是个坏主意。散列函数值总是被视为一个整体。
对于“如何计算 64 位哈希”的隐含问题:您的预期用途是什么?请记住,对于加密强度哈希函数来说,64 位太少了。
使用 CRC 来防止随机更改。
使用 HMAC 防止攻击者更改您的文件。HMAC 使用生成和验证标签所必需的密钥。HMAC 的结果与底层散列函数一样长(例如,HMAC-SHA1 为 20 个字节),但它经常被截断。即根据 NIST SP 800-107 p.14 64-96 位对于大多数应用程序来说应该足够了。
64 位对于散列来说很小,通常,散列应该被视为一个整体。
现在,你需要这些 64 位来做什么?答案将取决于预期的使用情况。
请记住,现在 md5 已经很糟糕了,64 位的安全性非常低。
如果您只需要针对随机更改进行完整性检查,那么其他答案中给出的简单校验和可能就足够了。
如果您需要加密强度来确保原始内容,那么 64 位太弱了。更好地使用完整算法的全部价值,即不是 MD5。SHA1 仍然可以,但为了长期安全,最好使用 SHA256。甚至如另一个答案中所述,使用 HMAC 更进一步。
使用加密哈希的截断值没有任何问题。实际上,SHA224/384 是通过使用不同的初始化向量计算一个 SHA256/512 哈希然后截断结果来计算的。但是,这仅对加密哈希有效。对于普通的校验和和表哈希来说,这可能是个坏主意。
使用 OpenSSL 的 API 进行计算。(www.openssl.org)。