在阅读了关于SipHash的一些优秀论文之后,我了解到良好的非加密哈希(例如MurmurHash和CityHash)对于MAC使用而言是不安全的,这是由于将Hash表的简并性转化为一种DDos攻击成为可能的列表和可预测的冲突。

中心假设是,可能建立多个独立于密钥的冲突,因为内部哈希循环的演化与密钥无关。

推理和解决方案很聪明,但是我看到它需要加密专家对算法进行人工研究。这个结论并非来自自动化工具。我猜想MurmurHash的近乎完美的分布和雪崩将击败这种自动化分析。但是我可能是错的。

我想将此学习应用于xxHash。考虑一下这是一个学习练习。

xxHash似乎避免了SipHash论文中描述的特定问题,方法是在内部循环开始之前就将密钥集成到内部状态中。结果,由于下一个内部状态取决于前一个内部状态,因此连续两个内部状态之间的差异不能独立于密钥。因此,它看起来像可以防止秘密密钥无关的冲突的存在,并且可以解决或部分解决防冲突属性。

当前,xxHash并不是加密的,主要是因为其输出为32-位。但是,从中创建64位和128位变体可能很简单。

因此,我们假设32位输出不是问题(可以使用蛮力解决方案,但是如果这是唯一的解决方案,则将基本原理视为“大约可以”)。

问题:是否有一种方法可以通过人工分析或自动工具来分析xxHash并判断该哈希函数是加密的还是不是加密的?如果没有,需要解决什么?

PS:作为显而易见的信息来源,让我们检查一下Wikipedia是什么加密哈希函数。显然,要使原本已经很好的Hash函数成为加密函数,只需具备原像和抗碰撞功能。这是正确的吗?

[编辑]

这是为xxHash产生独立于密钥的冲突的候选解决方案。好吧,差不多。请注意,存在许多限制,并且由于密钥的缘故,不能保证此技巧有效。但是,在最佳情况下,它很有可能以50%的概率工作。

1)在$ P $位置,例如$ P $是$ 4 $的倍数,有一个32位序列$ S $。

2)将值$ A = $ 0xBD1C0000加到$ S $。这将为$ Op1(S)= S * prime2 $添加一个固定值,即$ Op1(A)= A * prime2 = 000A0000 = bit18 $(由于乘法传递性

3)但是,我们真正想要的不是添加$ bit18 $,而是修改$ op1(S)$的第18位,因此从0修改为1。原因是,如果$ Op1(S)&bit18 == 1 $,加上$ bit18 $,由于进位溢出,我们不仅会修改第18位,而且还会修改一个或几个其他高位。由于我们希望得到可预测的结果,因此我们希望避免这种情况。

4)因此,我们需要选择包含序列$ S $的$ P $,例如$ Op1(S)$遵守此条件。 (第18位= 0)。因为对于一个随机输入,$ Op1(S)$的第18位有50%的机会等于0,所以对于任何足够长的输入,很可能会找到一个解决方案(S = 0为很明显的解决方案。)

5)但是,它还没有完成。然后将$ Op1(S + A)$添加到一个未知的内部状态,我们将其称为$ Z $。此内部状态取决于密钥。

6)与之前相同的条件:为了产生可控制的效果,我们需要$ Z $的第18位为0。但是,无法检查或保证该条件。因此,这里介绍的方法不能保证能正常工作(目前概率为50%...)

7)实际上,这还比这更糟:我们都需要确保$ Z $的第18位为零,并且由于进位溢出,将$ Z $和$ Op1(S + A)$的低位相加不等于第18位。

8)幸运的是,通过确保$ Op1(S)$的低位也为零(例如第17位,然后第16位,依此类推),可以使这种最新情况更有可能出现。不幸的是,每增加一个零条件,找到合适的$ S $的可能性就会降低。关于此最新条件,最好的输入是$ S = 0 $。

9)现在,如果满足上述所有条件,则$ Z1 = Z + Op1(S)的结果通过打开$ 18的第18位,对$进行了稍微更改:$ newZ1 = Z + Op1(S + A)= oldZ1 + bit18 $。

10)因此,$ Z2 = op2(Z1 )$也略有改变。由于$ Op2 $是32位字段的左旋转13位,因此我们有$ newZ2 = oldZ2 + bit31 $(bit31是最高位)。

11)因此,由于$ Op3 $是与质数的简单乘积,$ bit31 $的影响将保持不变。

12)此$ bit31 $将在位置$ P + 16 $处进行平衡。在这里,将$ B = $ 0x80000000的值添加到初始序列$ S2 $中就足够了,因为$ Op1(B)= 80000000 = B $。这将消除与上一轮的区别。这个密钥不需要什么特别的东西,它的成功率几乎是100%。

1)我们将进行另一种方法:将$ 1 $加到$ A = Op1(S )$。要获得此效果,只需将B6C92F47添加到位于位置$ P $的初始序列$ S $中,例如$ P $是4的倍数。

2)此方法的优点在于,只要$ Op1(S)$的最低17位与所有1都不同,它就可以工作。此外,很容易检查是否满足条件。

3)如果满足上述条件,则$ Op2 $只会将相加的1移位13位。因此$ B = Op2(A)$现在被+(2 ^ 13)修改。

4)现在我们可以计算对$ C = Op3(B)$的影响。由于$ newB = oldB + bit13 $,因此我们有$ newC = oldC + Op3(bit13)$。 $ Op3(bit13)= $ EF362000。

5)现在,我们必须在下一轮取消它。要获得此结果,只需添加-EF362000 = 10C9E000。要添加10C9E000,我们需要将981D2000添加到$ S2 $,因为$ Op1(981D2000)= 10C9E000 $。

6)现在,我们有几个值。将B6C92F47添加到$ P $位置的32位字段中,例如$ P $是4的倍数。然后在$ P + 16 $位置添加981D2000。此解决方案的可能性> 99.9%,不需要任何秘密密钥方面的知识。

评论

您称这两个输入中的哪个为“秘密密钥”?是“ seed”还是“ input”参数?

“秘密密钥” =“种子”

#1 楼

好吧,首先,您需要清楚各种加密原语的含义。


加密哈希函数;这是一个接受输入字符串并生成哈希的函数。这个想法是,我们不知道如何用相同的哈希创建两个输入字符串,因此哈希可以用作原始字符串的替代。现在,加密散列函数不需要私有密钥,因为我们需要假定任何人都可以计算它们。 xxHash显然不是加密哈希函数。而且,是的,有一些“键控哈希函数”确实采用了秘密密钥。 xxHash也不是其中之一。
消息验证码;这是一个需要消息和密钥的函数;它生成一个输出字符串(MAC)。这个想法是,如果某人不知道密钥,那么他们将无法为未看到其MAC的任何消息生成MAC。这更接近于您希望xxHash成为什么样子。而且,答案是是否为安全的消息身份验证代码,否则为“否”(如果答案为“是”,则将没有确定它的真正好方法)。

一种方法可以看到,事实上,即使对于不知道密钥的人,xxHash也不具有第二个原像抵抗能力。具体而言,给定有效的消息/ MAC对(消息长度至少为32个字节),可以构造第二个消息,其概率为$ p = 0.5 $,且评估为相同的MAC。请记住,这违反了消息身份验证代码安全性保证,不是专门因为它是冲突,而是因为它允许攻击者计算未获得其MAC地址的消息的MAC地址(并且这是与冲突无关的MAC值是否恰好是他之前见过的值)。

关于如何找到替代消息,您说过将其视为学习练习,可以视为读者的练习。但是,这是整体的工作原理。您在步骤$ X $进行了更改,这会干扰状态。您还需要在步骤$ X + 1 $处进行第二次更改(实际上,由于xxHash的工作原理,需要16个字节),而第二次更改会抵消第一次更改的影响,在准确处理更改后的消息时保留内部状态与原始消息的相应步骤相同。之所以存在成功概率$ p = 0.5 $,是因为变化是否正是我们所期望的,取决于加法期间是否发生了某个内部进位。为此,我们如何安排这两个更改以实现此目标?

评论


$ \ begingroup $
感谢您的澄清,现在加密哈希和MAC之间的区别要好得多。
$ \ endgroup $
–青色
13年2月21日在10:18

$ \ begingroup $
这似乎是一个很好的答案。使得xxHash不适合MAC使用的原理似乎与针对MurmurHash的原理相同:主要是,声称可以伪造2个连续的序列,无论潜在的内部状态如何,它们都会相互抵消,从而使该操作独立于密钥。但是,如果能找到这样的连续序列,我会感觉更好。
$ \ endgroup $
–青色
13年2月21日在10:32

$ \ begingroup $
@Cyan:这是解决这一问题的第一步; xxHash中的步骤之一是赋值“ v1 + = XXH_LE32(p)* PRIME32_2”。假设在某个消息的某个特定块中,“ v1”的值为$ X $(您不知道)。此时如何修改正在处理的块,以使此步骤后的“ v1”值为$ X + A $(对于您选择的值为$ A $)?
$ \ endgroup $
–雨披
13年2月22日在3:27

$ \ begingroup $
是的,可以肯定,在这种情况下,解决方案很容易。可以先创建一个A,然后再创建-A。问题是,这还不是全部操作。全行是:v1 + = XXH_LE32(p)* PRIME32_2; v1 = XXH_rotl32(v1,13); v1 * = PRIME32_1;仅操作1可以满足您的假设,操作2使其更复杂,但我认为仍然可以找到解决方案。但是操作3(v1 * = PRIME32_1;)似乎使一切变得混乱。我看不出如何使它“独立于X”,这就是重点。
$ \ endgroup $
–青色
13年2月22日在10:15



$ \ begingroup $
@Cyan:我说这是第一步。找到攻击的步骤2是“我们如何选择A,以便轮换后我们得到可预测的结果;如果此时实际数据包的值为$ Y $,则我们更改后的数据包很有可能是$ Y + B $(对于我们知道的某些$ B $)。最初,我找到了一个$ A $,它将保持$ p = 0.5 $;现在,我看到其他具有$ B $值且具有更高概率的$ A $值。无论如何,请执行步骤1;否则,请执行步骤1。您将从中学到东西。
$ \ endgroup $
–雨披
13年2月22日在16:21