【问题标题】:Is any 64-bit portion of a 128-bit hash as collision-proof as a 64-bit hash?128 位散列的任何 64 位部分是否与 64 位散列一样防冲突?
【发布时间】:2012-07-13 14:17:45
【问题描述】:

我们正在努力解决我们开发团队的内部争论:

我们正在寻找一个 64 位 PHP 哈希函数。我们找到了PHP implementation of MurmurHash3,但 MurmurHash3 是 32 位或 128 位,而不是 64 位。

同事 #1 认为,要从 MurmurHash3 生成 64 位散列,我们可以简单地对 128 位散列的第一个(或最后一个,或任何一个)64 位进行切片,并且它将是防冲突的作为原生 64 位哈希函数。

同事 #2 认为,我们必须找到一个原生 64 位散列函数来减少冲突,并且 128 位散列的 64 位切片不会像原生 64 位散列那样防冲突。

谁是对的?

如果我们采用 SHA1 等加密哈希的第一个(或最后一个,或任何一个)64 位而不是 Murmur3,答案是否会改变?

【问题讨论】:

  • 目标是什么?是加密的吗?如果是这样,就没有真正安全的 64 位散列函数。
  • 把这个问题移到crypto.SE不是更好吗?
  • @dystroy 可能,但不幸的是,这里不一定是获得所需专业知识的答案的地方。
  • 目标是一个简单的哈希,而不是加密。我不知道crypto.SE,但如果这是解决此类问题的更好地方,我愿意将其发布到那里。

标签: hash cryptography sha1 murmurhash


【解决方案1】:

由于雪崩效应,强散列是指源中的单个位变化导致散列的一半位平均翻转。那么,对于一个好的散列,“散列”是均匀分布的,因此每个部分或切片都受到相等且均匀分布的源比特数量的影响,因此与具有相同比特长度的任何其他切片一样强是。

我会同意同事 1,只要哈希具有良好的属性和均匀分布。

【讨论】:

  • 你认为这对于 MurmurHash3(非加密)和 SHA1(加密)都是正确的吗?
  • 假设 SHA1 更面向加密,而 Murmur 更面向性能,那么我会说 SHA1 更适合切片,因为加密强大的哈希函数旨在提供更均匀/均匀的分布。您应该根据您的要求分析碰撞和速度。像往常一样,可能会有一个权衡。
  • Murmur 不是加密的强哈希,我会认真建议您查看 SHA-1 或 SHA-256(尽管后者肯定又慢了一些)。由于生日悖论,64 位散列函数只能提供大约 32 位的抗碰撞攻击能力。如果不去特意寻找它们,你不会马上遇到碰撞,但这也不是完全不可能的。
【解决方案2】:

如果您有真正的随机、均匀分布的值,那么“切片”将产生完全相同的结果,就好像您从一开始就使用较小的值一样。要了解原因,请考虑这个非常简单的示例:假设您的随机生成器输出 3 个随机位,但您只需要一个随机位即可使用。假设输出是

b1 b2 b3

可能的值是

000, 001, 010, 011, 100, 101, 110, 111

所有发生的概率都是 1/8。现在,无论您出于目的从这三个中切出什么位-第一,第二或第三-无论位置如何,拥有“1”的概率始终为1/2-对于“0”也是如此'。

您可以轻松地将此实验扩展到 128 位中的 64 位情况:无论您切片哪些位,在某个位置以 1 或 0 结束的概率都是二分之一。这意味着如果你有一个从均匀分布的随机变量中提取的样本,那么切片不会增加或减少发生碰撞的可能性。

现在一个很好的问题是,随机函数是否真的是我们可以做的最好的防止碰撞的方法。但事实证明,只要函数偏离随机值,发现碰撞的概率就会增加。

加密哈希函数:同事 #1 获胜

现实生活中的问题是哈希函数根本不是随机的,相反,它们是无聊的确定性。但是密码散列函数的设计目标如下:如果我们不知道它们的初始状态,那么它们的输出将在计算上与真正的随机函数无法区分,即没有计算上有效的方法来区分散列输出之间的差异和真正的随机值。这就是为什么如果你能找到一个“鉴别器”,你会认为散列已经被破坏了,这是一种将散列与概率高于一半的真实随机值区分开来的方法。不幸的是,我们无法真正证明现有加密哈希的这些属性,但除非有人破解它们,否则我们可以假设这些属性具有一定的信心。这是一个paper 的示例,该示例是关于 SHA-3 提交之一的区分符,说明了该过程。

总而言之,除非为给定的加密哈希找到区分符,否则切片是完全可以的,并且不会增加冲突的可能性。

非加密哈希函数:同事 #2 可能会获胜

非加密哈希不必满足与加密哈希相同的一组要求。它们通常被定义为非常快并且“在理智/仁慈的条件下”满足某些属性,但如果有人试图恶意操纵它们,它们可能很容易达不到要求。这在实践中意味着什么的一个很好的例子是今年早些时候提出的对哈希表实现 (hashDoS) 的计算复杂性攻击。在正常情况下,非加密哈希工作得非常好,但它们的抗碰撞性可能会被一些聪明的输入严重破坏。加密散列函数不会发生这种情况,因为它们的定义要求它们不受各种巧妙输入的影响。

因为有可能,有时甚至很容易,为非加密散列的输出找到像上面这样的区分符,我们可以立即说它们不符合加密散列函数的条件。能够分辨出差异意味着输出中的某个地方存在模式或偏差。

仅这一事实就意味着它们或多或少地偏离了随机函数,因此(根据我们上面所说的)碰撞可能比随机函数更有可能发生。最后,由于在完整的 128 位中已经发生冲突的概率较高,因此较短的输出不会变得更好,在这种情况下冲突的可能性更大。

tl;dr 截断加密散列函数是安全的。但是,与将具有较大输出的非加密哈希截断为 64 位相比,使用“本机”64 位加密哈希函数会更好。

【讨论】:

  • 感谢您非常彻底的回复。这很有帮助!
【解决方案3】:

如果不提这个问题,这个问题似乎不完整:

对于特定的输入类别,某些哈希可证明是 perfect 哈希(例如,对于长度为 n 的输入,对于 n 的某个合理值)。如果您截断该哈希,那么您很可能会破坏该属性,在这种情况下,根据定义,您会将冲突率从零增加到非零,并且您已经削弱了该用例中的哈希。

这不是一般情况,但它是截断哈希时合理关注的一个示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    相关资源
    最近更新 更多