为什么使用 MD4 进行缓存?

信息安全 哈希 缓存
2021-08-18 10:59:09

ccache是一种流行的工具,用于加速使用 GCC 和其他编译器进行重新编译。它通过缓存以前的编译并检测何时再次完成相同的编译来工作。检测是使用 MD4 哈希完成的。

我很好奇(a)为什么这样的缓存工具会使用任何加密散列函数,以及(b)在所有可用的加密散列函数中,为什么要特别使用 MD4。

关于(a),使用加密哈希函数有什么好处,而不是一些没有考虑加密设计的哈希函数?例如,Java 的内置散列函数似乎与密码学中使用(或以前使用)的已知散列函数不对应。为什么不使用这些非加密哈希函数之一呢?鉴于 MD4 的已知弱点,我无法想象选择它是出于对更高安全性的渴望。

关于(b),假设使用加密哈希有一些基础,为什么特别是 MD4?我知道使用现代加密哈希函数是没有意义的,因为它们通常是计算密集型的,这违背了缓存工具加快访问时间的目的。因此,必须至少部分使用 MD4 以提高速度。但它绝对是最快的加密哈希函数,还是有其他更快的?如果它不是最快的,MD4 在缓存中还有哪些其他优势(例如,超过 MD5)?

2个回答

密码散列函数通常具有稍微不同的输入产生截然不同的输出的特性。任何碰撞通常应该有非常不同的输入。

此属性不适用于大多数非加密校验和。小的更改可能会导致相似的校验和,并且在某些极端情况下,一些小的更改可能会以生成相同校验和的方式相互抵消。

源代码的更改通常很小,因此在检查源代码更改的上下文中,非加密校验和的冲突风险非常高。例如,版本控制工具 git 使用 SHA-1 哈希作为代码修订的唯一标识符。

为什么特别是 MD4?好吧,你必须向 ccache 开发人员询问这个问题。这是一个相当古老的工具,而且 MD5 直到 1992 年才标准化。可能 MD4 只是在开发此功能时可用的最明显的选择,后来没有人觉得需要替换算法,因为它做了它应该做的事情。

通常的非加密散列(如 CRC-32)在统计上是好的,但这里缓存想要避免的是误报——重新编译被声明为与前一个相同,但不是。仅产生 32 位的普通非加密哈希具有太高的误报风险,仅从其输出大小来看,而不管其统计质量如何。加密哈希具有更大的输出,这使得误报的风险可以忽略不计。

这不是一个安全问题:所有的输入都来自用户,所以如果用户故意进行碰撞,他只是在与自己对抗。因此,可以使用密码破译的散列函数。

现在对于 MD4 而不是更常见的函数(例如 MD5 或 SHA-1)的具体选择,只能推测,但我的猜测是它与性能有关;毕竟,ccache 就是为了让编译更快。MD4 非常快(在某些平台上甚至比 CRC-32 还要快)。当然,散列比任何编译过程甚至读取文件都快,因此使用 MD5 代替 MD4 很可能对 ccache 的整体性能没有显着影响。在实践中,许多与性能相关的决策都是凭直觉做出的,而没有考虑实际措施来查看是否存在必须解决的性能问题。

这个库的工作来看,很少有加密散列函数至少和 MD4 一样快。BLAKE2是 BLAKE SHA-3 候选算法的最新衍生产品,对于接近 MD4 级别性能的加密安全散列函数,它可能是您的最佳选择。但是,正如我在上面所写的,在 ccache 的情况下,性能很可能不是真正的问题。