在不考虑碰撞可能性的情况下,使用MD5作为哈希值可以达到什么字符串长度?
这可能是通过为特定字符集中的每个可能字符串生成MD5哈希来计算的,增加长度,直到第二次出现哈希(冲突)。没有碰撞的字符串的最大可能长度将比碰撞对中的最长字符小一个字符。
这已经针对MD5,SHA1等进行了测试吗?
答案 0 :(得分:72)
他们的方法将在2013年1月之前发布,但现在可以使用论文中的数字验证他们的碰撞:
>>> from array import array
>>> from hashlib import md5
>>> input1 = array('I', [0x6165300e,0x87a79a55,0xf7c60bd0,0x34febd0b,0x6503cf04,
0x854f709e,0xfb0fc034,0x874c9c65,0x2f94cc40,0x15a12deb,0x5c15f4a3,0x490786bb,
0x6d658673,0xa4341f7d,0x8fd75920,0xefd18d5a])
>>> input2 = array('I', [x^y for x,y in zip(input1,
[0, 0, 0, 0, 0, 1<<10, 0, 0, 0, 0, 1<<31, 0, 0, 0, 0, 0])])
>>> input1 == input2
False
>>> md5(input1).hexdigest()
'cee9a457e790cf20d4bdaa6d69f01e41'
>>> md5(input2).hexdigest()
'cee9a457e790cf20d4bdaa6d69f01e41'
更新:该论文已于2013年3月发布:Tao Xie and Fanbao Liu and Dengguo Feng - Fast Collision Attack on MD5
但是,如果你有更多的空间可以玩,几千字节的碰撞要快得多 - 它们可以在几小时内在任何普通计算机上计算。
之前的最短碰撞使用了至少两个值得输入的MD5块 - 即128字节,1024位。第一个块中的前缀可以由攻击者任意选择,其余的将被计算并显示为乱码。
以下是两个不同碰撞输入的示例,您可以在Python中自己尝试:
>>> from binascii import unhexlify
>>> from hashlib import md5
>>> input1 = 'Oded Goldreich\nOded Goldreich\nOded Goldreich\nOded Go' + unhexlify(
... 'd8050d0019bb9318924caa96dce35cb835b349e144e98c50c22cf461244a4064bf1afaecc582'
... '0d428ad38d6bec89a5ad51e29063dd79b16cf67c12978647f5af123de3acf844085cd025b956')
>>> len(input1)
128
>>> md5(input1).hexdigest()
'd320b6433d8ebc1ac65711705721c2e1'
>>> input2 = 'Neal Koblitz\nNeal Koblitz\nNeal Koblitz\nNeal Koblitz\n' + unhexlify(
... '75b80e0035f3d2c909af1baddce35cb835b349e144e88c50c22cf461244a40e4bf1afaecc582'
... '0d428ad38d6bec89a5ad51e29063dd79b16cf6fc11978647f5af123de3acf84408dcd025b956')
>>> md5(input2).hexdigest()
'd320b6433d8ebc1ac65711705721c2e1'
在一个215节点的Playstation 3群集上生成这两个特定输入需要2天,by Mark Stevens:)
答案 1 :(得分:10)
birthday paradox的数学使得碰撞概率的拐点大致在sqrt(N)附近,其中N是散列函数中不同的bin的数量,因此对于128位散列,就像你一样大约64位,你可能有1次碰撞。所以我的猜测是完整的8字节字符串,它有可能发生冲突,对于9字节字符串,它极有可能。
编辑:这假设MD5哈希算法导致从输入字节串到接近“随机”的输出哈希的映射。 (与在可能的哈希集合中更均匀地分配字符串的那个相比,在这种情况下,它将更接近16个字节。)
另外,对于更具体的数字答案,如果你看one of the approximations计算碰撞概率,你会得到
p(k)≈1 - e -k(k-1)/(2 * 2 128 )其中k =可能输入空间的大小= 2 m 其中输入字节串是m位长。
一组8字节字符串:p(2 64 )≈1 - e -0.5 ≈0.3935
9字节字符串的集合:p(2 72 )≈1 - e -2 144 /(2 * 2 128 ) = 1 - e -2 15 = 1 - e -32768 ≈1
另请注意,这些假设是完整的m / 8字节字符串集。如果您只使用字母数字字符,则需要更多字节才能获得可能的冲突。
答案 2 :(得分:1)
我怀疑是否有任何有用的长度你不会发生碰撞。那些算法并没有真正用于此目的。它意味着尝试对数据中的微小变化(如损坏的文件)保持唯一,而不是对所有可能的数据集都是唯一的。