假设我想设计一个包含一些加密哈希的协议(或数据格式或类似格式),并希望它尽可能地面向未来,即我想避免加密技术的突破使我的旧数据不安全。
如果我仅使用一种哈希算法,那么运气不好的话,我会选择几年后将被破坏的算法。

例如,MD4(1990年出版)首次发生了碰撞攻击在1995年,到2007年,这些算法甚至比计算哈希本身还要便宜。

因此,我们的想法是将多个这样的算法组合在一起,从而只破坏其中一个(或一些)算法就可以了。不会损害组合结构的安全性-必须将它们全部破坏。

我不关心计算多个散列而不是计算多个散列所带来的效率损失,我只是想确保更好的密码分析。

所以,如果我有哈希函数$ H_1 $,$ H_2 $,...,$ H_n $。

如何结合它们以形成像它们中的任何一个一样安全的哈希函数?

两个基本概念却无法按预期工作: br />简单连接输出:$ H_1(m)|| H_2(m)|| ... || H_n(m)$。

对于碰撞攻击来说应该是相当安全的,但是对于像前攻击而言,这是最安全的,因为它们是其中最弱的一个(以及其他
<可以用来检查我是否找到了正确的原像。)链接功能:$ H_1(H_2(...(H_n(m)...))$

对于原像攻击,您现在需要将其全部破坏。但是Hn中的
碰撞也很容易导致结果碰撞。不太容易利用,因为您随后需要
必须获得先前的原像。)


结合它们的任何更好的方法?或者这是一个愚蠢的主意全部?


需要说明的是:除了最困难的组件功能外,我实际上并不需要更多的安全性,但我至少需要那么多的安全性。 (在这里使用更多的空间并不是真正的问题。)

对于原图像,我现在主要担心有人找到原始的原图像(大约与散列输出的大小有关),在简单连接的情况下,看起来这和最弱散列一样困难。
我不太在乎有人在构造一个新的哈希-听起来很困难,但事实并非如此如果消息的大小可以根据需要增加(每位哈希值一个块或大约一个块),并且压缩功能受到碰撞攻击,如Joux所示。

评论

海事组织,这是一个坏主意。您没有任何合理的依据来相信您得到的函数比产生相同长度输出的任何其他不间断哈希函数更安全。举例来说,您将两个哈希函数进行XOR运算。您怎么知道将来的一些研究人员不会在两个哈希函数的位之间找到任何相关性,从而使XOR比任何一个都弱?
我知道这一点,这就是为什么我没有在提案清单中包括XOR的原因。我正在寻找有关如何使其安全的其他想法。 (此外,我不受“相同尺寸”的限制。)

我仅以XOR为例。 XOR没有什么特别的。我的观点是,无论您使用哪种操作将它们组合在一起,都可能添加其自身的漏洞。

@大卫:这是不正确的。取决于您感兴趣的属性,可以证明组合比单独使用两个函数更安全。以图像前电阻为例。函数$ H_1(m)\ | H_2(m)$的原图像要求您找到一条消息$ m $,该消息是$ H_1 $和$ H_2 $的原图像。

这篇论文刚出来,您可能会发现有趣。

#1 楼

SSL / TLS在其内部“ PRF”(实际上是密钥派生功能)的定义中对MD5和SHA-1进行了组合。对于给定的哈希函数,TLS定义了一个KDF,该KDF依赖于HMAC,而HMAC则依赖于哈希函数。然后,两次调用KDF,一次使用MD5,一次使用SHA-1,然后将结果异或在一起。这个想法是为了抵抗MD5或SHA-1中的密码分析中断。请注意,对两个哈希函数的输出进行异或运算取决于微妙的假设。例如,如果我为固定常数$ C $定义$ \ mathrm {SHB-} 256(m)= \ mathrm {SHA-} 256(m)\ oplus C $,那么SHB-256就是一个很好的哈希用作SHA-256;但两者的XOR总会产生$ C $,对于哈希目的而言,这根本不好。因此,TLS的构造并没有真正受到科学权威的认可(恰好没有被破坏)。 TLS-1.2不再使用该组合。它依赖于具有单个可配置哈希函数的KDF,通常为SHA-256(在2011年是明智的选择)。哈希函数的构建。该书由Joux于2004年出版,然后由Hoch和Shamir于2006年推广,涉及涉及迭代和级联的大量构造。但是请留意细则:这并不是要真正解决哈希函数中的弱点,而是要使自己的钱物有所值。也就是说,如果您将一个具有128位输出的哈希函数和另一个具有160位输出的哈希函数进行连接,然后将结果连接起来,那么抗冲突性将不会比这两者中最强的一个差; Joux展示的是,它也不会更好。使用$ 128 + 160 = 288 $位的输出,您可以瞄准$ 2 ^ {144} $的阻力,但是Joux的结果表明您不会超出$ 2 ^ {87} $的范围。

因此,问题就变成了:是否有一种方法,如果可能的话,可以组合两个哈希函数,使得结果与两个哈希函数中的最强函数一样具有抗冲突性,而又不会导致串联的输出扩大?在2006年,Boneh和Boyen发表了一个结果,该结果简单地指出答案是“否”,但前提是每个哈希函数只能评估一次。

编辑:Pietrzak在2007年解除了后一种情况(即多次调用每个哈希函数无济于事)。

评论


$ \ begingroup $
我稍微编辑了一个问题-即使使用更多空间,仅获得两者中最难解决的力量就足够了。我只想确保我不会以某种方式获得比最难的人少的安全性(不知道哪个更难)。 (我仍然必须阅读您的大多数链接。)
$ \ endgroup $
–PaŭloEbermann
11年7月29日在19:08

$ \ begingroup $
@Paulo:同时获得原像抗性和抗碰撞性似乎是一个有趣的问题。我不知道有关该主题的任何现有研究。对于第二张原图,这很容易:抵抗第二张原像至少要等于抵抗碰撞(我们通常希望它更高,但这已经是事实)。
$ \ endgroup $
–托马斯·波宁(Thomas Pornin)
2011年7月30日,下午2:42

$ \ begingroup $
2013年,Arno Mittelbach为比串联短的组合器提供了新的定义(和方法),它提供了与两个哈希函数中的较强者(以及其他属性类似)相同的抗碰撞性,并增加了至少IRO是功能之一。 eprint.iacr.org/2013/210
$ \ endgroup $
–archie
13-10-30在8:50



#2 楼

您对原始问题的想法是正确的。如果要防止的是原图像,则链接哈希函数会产生至少与其两个分量中最强的函数一样强的函数:

$$ H _ {\ circ}(x)= H_0 (H_1(x))$$

如果要防止碰撞,则串联的强度至少要强于其两个分量中的最强强度:

$ $ H_ {|}(x)= H_0(x)| H_1(x)$$

组合函数可能还需要其他一些属性,例如伪随机性。对于伪随机性,您可以将两个哈希函数结合在一起,例如: >最棘手的部分(如您所观察到的)是您是否要拥有这些属性中的多个。到目前为止,我所知道的最好的研究是Anja Lehmann的论文。 (您可以在Tahoe-LAFS项目的“一百年密码学”维基上找到有关此主题和相关主题的讨论。)

如果我需要安全哈希函数中的多个属性,并且不必理会额外的CPU周期,也不介意将输出大小增加一倍,那么我可能会使用雷曼(Lehmann)的$ Comb_ {4P} $结构,而不必太担心结果组合功能可能无法保留预图像抵抗力。

如果您确定只需要一个属性(请注意此处-请仔细考虑,并明确写下您依赖的一个或多个属性,以及攻击者可以做什么)每个可能的属性均不成立),则可以安全地使用上述组合器之一。

顺便说一句,该论文还包含了在该线程中讨论的其他两个主题的非常有趣的结果:是否可以具有组合函数$ C(H_1,H_2)$,其抗碰撞性比$的强度强。 H_1 $加上$ H_2 $的强度(她肯定地回答),以及SSL和TLS结合SHA1和MD5的方式是否安全(答案:有点...)。

评论


$ \ begingroup $
我总是感到不安,直接将一个哈希函数的结果反馈给另一个哈希函数。我知道从理论上讲应该很好,但是以某种方式看来我的输出范围实际上可能小于整个可能的输出范围。当然,如果我将它与自身结合起来使用,我会感觉更好,但是这可能也有点愚蠢。
$ \ endgroup $
–恶毒
2011年8月4日在23:12

$ \ begingroup $
@无所不能:我认为这就是为什么通常使用H₀(H₁(x)| X)等代替直接使用H directly(H₁(x))的原因-具有更好的原像电阻,同时仍然没有冲突,而不是只有一个哈希。
$ \ endgroup $
–PaŭloEbermann
2011年8月5日,0:35

$ \ begingroup $
链接哈希函数不是一个好主意。假设$ H_0 $是一个随机预言(因此具有完美的单向/前映像抵抗性)。现在假设$ H_1 $是一个常数函数(例如,它将每个输入映射到$ 0 $)。然后,组合$ H_0(H_1(x))$不具有像前抗性,因为它是一个常数函数。
$ \ endgroup $
–阿诺·米特尔巴赫(Arno Mittelbach)
2013年12月14日下午16:28

#3 楼

我相信@Thomas会给出详尽的答案。在此期间,我只想指出您的第一个构造$ H_1(m)|| H_2(M)$的耐碰撞性并不比$ H_1(M)$好多少。请参阅本文的第4节:

迭代哈希函数中的多重冲突。在级联结构中的应用。

评论


$ \ begingroup $
实际上,对于所有有用的电阻值(原像,碰撞,第二原像),我满足的条件是电阻(组合)= max(电阻(H1),电阻(H2))。
$ \ endgroup $
–PaŭloEbermann
2011年7月29日在17:56

$ \ begingroup $
看来这里描述的攻击都是从压缩功能中的冲突开始的,即通过为单个消息选择正确的块来对长消息生成多重攻击。我认为它们并不真正适用于短消息(大约哈希输出大小等)或某种固定格式的消息(没有足够的空间来插入随机冲突)。
$ \ endgroup $
–PaŭloEbermann
2011年7月29日在18:07

$ \ begingroup $
Paulo指出,多重碰撞基于压缩函数中的碰撞。如果有其中一些,则可以利用哈希函数的迭代结构(主要是Merkle-Damgaard)。但是,与构象合并器$ H_1(m)\ | H_2(m)$无关。
$ \ endgroup $
–阿诺·米特尔巴赫(Arno Mittelbach)
2013年12月14日的16:32

#4 楼

好吧,我看到了两种切实可行的方法来抵抗这些漏洞。

如果要使用两个哈希函数,请确保将HMAC中的原始数据反馈给第二个函数:

hash = algo1(data)
hash = hmac(algo2, data, hash)


这里的好处是,由于MAC的缘故,algo1的任何冲突都不会自动成为algo2的冲突。因此,为了使碰撞攻击起作用,攻击者必须使用相同的源数据为两个功能找到碰撞。实际上,这比独立地攻击两个功能要困难得多(这至少与攻击两个功能中的最强功能一样困难)。

另一种方法是简单地迭代单个哈希功能(带反馈)。这看起来与以前的算法相似。

hash = hmac(algo1, pack('N', 1), data)
for (i = 0 ... n) 
    hash ^= hmac(algo1, hash, data)


其中n大于或等于0。它越大,计算速度就越慢。请注意,这基本上只是带有空盐的PBKDF2,并且将length参数设置为哈希的输出大小。

“拉伸”的好处在于,它既可以防止原图攻击也可以防止碰撞攻击,因为即使攻击者能够在第一轮找到原图,仍然需要多轮攻击。考虑到反馈,攻击特定回合所需的数据将在下一轮被销毁。因此,即使攻击者确实设法完成了一轮原像攻击,也很难(如果不是不可能)攻击另一轮。

评论


$ \ begingroup $
我不明白这一点。当然,algo1的碰撞不会自动成为algo2的碰撞。但是您的整体算法可能会发生基础算法所没有的冲突。我没有合理的理由认为新创建的冲突不会比基础哈希函数中可能发生的冲突更糟。从好的方面来说,这可能不会弱于两个哈希函数中的强者。因此,如果其中一个已损坏但不是两个都损坏,则可能会没事。
$ \ endgroup $
– David Schwartz
2011年8月23日12:30



$ \ begingroup $
@David:好吧,如果两个都坏了,那将无济于事...重点是要与最安全的功能一样安全(如果不是更好的话)...
$ \ endgroup $
–ircmaxell
11年8月23日在15:18

#5 楼

怎么样,比如对基本哈希函数输出的位进行交织以生成密钥(依次从每个哈希中获取一位,跳过没有剩余未合并位的哈希),然后使用每个具有很多位的基本哈希函数生成HMAC可以使用的密钥数量: H(x)= HMAC_ {H_0}(K(x),x)\ | HMAC_ {H_1}(K(x),x)\ | HMAC_ {H_2}(K(x),x)$$

这样,每个HMAC理论上都依赖于所有哈希算法。您可能不希望将$ K(x)$的前几位用于$ HMAC_ {H_0} $的密钥,而是将$ HMAC_ {的后几位使用$ K(x)$ H_1} $,依此类推,将$ K(x)$与自身连接在一起,以获得足够的位来键控所有HMAC。 )$(等)作为您的哈希,对于$ H $的每次调用(以及对$ K(x)$的相应调用),可能以不同的顺序使用基本哈希函数。

评论


$ \ begingroup $
交织而不是连接位的目的是什么?您认为此组合具有其他属性没有的哪些属性?
$ \ endgroup $
–otus
16年1月16日在8:30

$ \ begingroup $
将哈希输出交织成HMAC密钥意味着每个HMAC都依赖于每个哈希算法中的位,而级联最终将导致每个HMAC只是$ HMAC_ {H_n}(H_n(x),x)$。如果密钥依赖于所有基本哈希函数,则伪造HMAC最终连接的任何单个元素都应要求破坏所有基本哈希函数(或至少破坏用于该密钥的每个哈希的位)。
$ \ endgroup $
– Extratraus
16年1月16日在22:32

$ \ begingroup $
如果您的等式对每个HMAC使用完整的$ K $,则串联也同样适用-我错过了您说可能会丢掉一些位的那部分。所谓“什么特性”,是指您认为此处的抗碰撞性,原像抗性等。
$ \ endgroup $
–otus
16年1月17日在10:04

$ \ begingroup $
我希望抗冲突性至少与最强的哈希值一样好(就像仅填充基本哈希值一样,因为HMAC最终是对基本哈希值的调用的输出)。由于最终输出的每个部分不仅取决于数据,而且取决于从所有基本散列派生的伪随机密钥,因此我期望原像电阻具有类似的属性。与简单哈希不同,找到一个基本哈希的原图像仍然不能让您使用该字符串来生成没有密钥的其他HMAC,因此您不能使用其他哈希来选择可能的原图像。
$ \ endgroup $
– Extratraus
16 Jan 17 '19:32



#6 楼

有一篇研究论文解释了为什么链哈希不能从随机预言的不可区分性上提供更好的安全性

评论


$ \ begingroup $
但是这个问题不是真的关于H(H(x)),在两种情况下H都是相同的散列。
$ \ endgroup $
– CodesInChaos
13年2月6日在15:21

$ \ begingroup $
感谢您提供的链接,但是本文不适用于我使用不同哈希函数的情况。
$ \ endgroup $
–PaŭloEbermann
13年2月6日在18:52

$ \ begingroup $
这是我对您的问题的误解。我没有彻底检查不同哈希函数的情况。
$ \ endgroup $
–好奇
13年2月6日在19:42

#7 楼

使用修改后的双工结构。首先通过$ h_1 $运行消息,然后获取结果的最后32位,然后将其与512位IV的前32位进行XOR运算。然后将IV放入512位哈希函数$ h_2 $。然后使用哈希函数的前32位并将其放入哈希缓冲区。重复此过程,直到将足够的哈希放入缓冲区中为止。我知道,速度是$ n(h + i)$,其中$ h $是$ h_1 $的速度,$ i $是$ h_2 $的速度,$ n $是回合数。但是,如果$ h_1 $和$ h_2 $确实非常快,那将是个好消息!

评论


$ \ begingroup $
感谢您为新的“解决方案”集思广益...您是否有分析为什么这比其他结合方法更好?头几位或最后几位在哪方面特别?
$ \ endgroup $
–PaŭloEbermann
13年7月5日在8:54

$ \ begingroup $
好的,它具有良好的雪崩特性,可以很好地抵抗长度扩展攻击,并且具有h1和h2的特性(仅用于良好的h1 / h2)。首位/末位是特殊的,因为它们可抵抗长度扩展攻击。
$ \ endgroup $
–加弗里尔·费里亚(Gavriel Feria)
13年7月6日在22:43

$ \ begingroup $
您还可以在h2,h3,h4,...,hn之间切换,并在某些条件下切换为1。
$ \ endgroup $
–加弗里尔·费里亚(Gavriel Feria)
13年7月6日在22:46

$ \ begingroup $
为什么有人不赞成这个答案?这是一个很好的解决方案。
$ \ endgroup $
–加弗里尔·费里亚(Gavriel Feria)
13年7月6日在23:02

$ \ begingroup $
我忘记了一些。 $ h_1 $中的冲突不一定表示结果哈希值$ h_p $中的冲突,概率为$ 2 ^ {-224} $。 $ h_2 $中的冲突并不意味着结果散列$ h_p $中的概率为$ 2 ^ {-256} $的冲突。
$ \ endgroup $
–加弗里尔·费里亚(Gavriel Feria)
13年7月14日在21:50



#8 楼

组合的哈希函数只是一个哈希函数,将具有它自己的理论和实践漏洞。

我的断言是,可以设计两个哈希函数$ H_1 $和$ H_2 $使得$ H_1 $好,$ H_2 $好,但是$ H_1 + H_2 $很弱。

因此,通过组合两个哈希函数,可以实现相反的效果。是否必须独立建立。

评论


$ \ begingroup $
如果只需要特定的组合器,通常可以创建至少与更强的哈希一样好的哈希函数。例如,串联第二个原像和碰撞。虽然这种组合可能比产生长哈希的一种算法弱。
$ \ endgroup $
– CodesInChaos
13年7月5日在21:11

$ \ begingroup $
我的观点是,如果您可以设计具有某些特征的哈希函数,则只需选择两个哈希函数并将其组合,就可以了。所以是的,您可能会有所改善。
$ \ endgroup $
– ddyer
13年7月5日在21:16

$ \ begingroup $
可证明的是,将两个散列连接起来与两个散列中的强者一样具有抗碰撞性。因此,与仅使用其中一种相比,它当然不会使事情变得更糟。它可能会错误地使用给定的输出大小或处理时间预算。
$ \ endgroup $
– CodesInChaos
13年7月5日在21:23

$ \ begingroup $
@ddyer因此,假设我们的串联函数为$ H(x):= H_1(x)|| H_2(x)= H_1(x)|| \ mathtt {1 ... 1} $。然后$ H(x_1)= H(x_2)$仍意味着$ H_1(x_1)= H_1(x_2)$,即,(对于防撞性)$ H $的强度与$ H_1 $相同。 (不过,它不像具有$ H $的类似$ H_1 $的设计那样强大,但是它的输出大小可能与$ H $相同。)
$ \ endgroup $
–PaŭloEbermann
13年7月6日在10:35



$ \ begingroup $
@ddyer的“透露信息”是对原像的抵抗。如果您关心碰撞和第二张原图,则串联很有用。组合器仅保留哈希的某些属性,而不是全部。
$ \ endgroup $
– CodesInChaos
2013年9月11日上午10:33