【发布时间】:2013-10-30 00:38:38
【问题描述】:
我想计算一组元素(无序列表)的 sha1 哈希值。我已经计算了每个元素的 sha1 哈希值。我正在考虑两种解决方案:
按元素的哈希值对元素进行排序并计算该列表的顶部哈希值。
将元素散列视为 160 位整数值并将它们异或(按位运算)合并为一个 160 位散列。
第二种解决方案在安全散列函数属性方面是否较弱? (抗原像性、抗二次原像性、抗碰撞性)。
【问题讨论】:
标签: hash
我想计算一组元素(无序列表)的 sha1 哈希值。我已经计算了每个元素的 sha1 哈希值。我正在考虑两种解决方案:
按元素的哈希值对元素进行排序并计算该列表的顶部哈希值。
将元素散列视为 160 位整数值并将它们异或(按位运算)合并为一个 160 位散列。
第二种解决方案在安全散列函数属性方面是否较弱? (抗原像性、抗二次原像性、抗碰撞性)。
【问题讨论】:
标签: hash
选项 1 是在 ERS 中所做的:该标准使用哈希树,其中每个节点包含一个哈希值,该哈希值是根据子节点的哈希值集计算得出的;由于顺序在树中并不重要,因此在散列之前按字典顺序对值进行排序。这很好,而且据我们所知是安全的。
选项 2 非常不安全:如果哈希函数有 160 位输出,那么我可以轻松生成 160 个随机输入,使得相应的哈希值构成向量空间的基础 GF(2) 160,此时我可以为 any 聚合哈希值生成匹配集。攻击成本可以忽略不计。
@paj28 建议的选项 3(将值排序以散列,然后散列它们)也很好,只要您使用明确的分隔符“连接”排序值。例如,如果您对包含“bar”和“foo”的字符串集进行哈希处理,您不希望获得与包含“ba”和“rfoo”的字符串集相同的哈希值。当所有要散列的值都具有相同的长度时,更容易获得安全的东西。
因此,使用选项 1:对集合中的每个值进行哈希处理,然后按字典顺序对哈希值进行排序,然后再次对排序后的值列表进行哈希处理。
关于选项 2 的攻击:这是线性代数。假设你有 k 个 n 位的向量,这样它们中的任何一个都不等于其他 k-1 个向量的 XOR (据说它们是线性独立的)。然后考虑一个新的随机向量v;这个向量等于某些k个向量的异或的概率等于2kn,即只要它很小k
递归:你很快就会得到 n 个向量,这些向量由 n 个比特组成,它们彼此线性独立。但是你不能走得更远,因为任何新向量与之前的 n 线性无关的概率已降至 0。 n 向量被称为 向量空间的基。
在这种情况下,向量是通过简单地散列值(随机值,或具有结构的值,没关系,因为散列函数充当随机器)获得。
对于给定的一组 k 向量,使用 @987654322 可以轻松确定新向量 v 是否与 k 向量线性无关@。同样的算法让你知道,一旦你有了一个基础,哪些你的 n 个基础向量应该被异或在一起以产生任何向量 v' .在这个问题的设置中,这意味着一旦我产生了 n 值 mi 使得 h(mi) 构成一个基,那么对于任何目标n位输出t,我可以使用高斯消去算出我的哪一个h(mi) 可以一起进行异或运算以准确地产生值 t。相应的 mi 值是 t 的原像集。
【讨论】:
另一个选项 (3) 是先对元素进行排序,然后使用不能作为元素一部分出现的分隔符将它们组合成单个字符串。
在这些可能性中,我最关心的有 2 个。我现在想不出如何以实际的方式攻击它,但这似乎是最危险的。
所以1和3基本没问题。但我会推荐 3,因为您正在按照预期的方式使用哈希。
【讨论】: