在混帐哈希碰撞

如果我在使用git时发生了散列冲突,会发生什么?

例如,我设法提交具有相同sha1校验和的两个文件,是否会注意到它或损坏其中一个文件?

可以改善生活,或者我将不得不改变一个新的哈希algorithm?

(请不要偏离这个问题,讨论这是多么不可能 – 谢谢)

如果两个文件在git中具有相同的哈希总和,则将这些文件视为相同。 发生这种情况的绝对不可能的情况下,你总是可以返回一个提交,并改变文件中的某些东西,使它们不会再发生碰撞。

在git邮件列表中看到Linus Torvalds的post“开始思考sha-256?” 。

一个SHA-1哈希是一个40hexstring…这是每个字符4位40 … 160位。 现在我们知道10比特大约是1000(准确的说是1024),这意味着有1000万000000000000000000000000000000000个不同的SHA-1散列… 10。

这相当于什么? 那么月亮是由大约10 47个primefaces组成的。 所以如果我们有10个月……而且你随机在这些月亮的其中一个上select一个primefaces,然后继续在它们上面再选一个随机primefaces……那么你可能会select同一个primefaces两次,两个git提交可能会有相同的SHA-1散列。

编辑:扩展在这个…你需要多less个提交在库之前,你应该开始担心碰撞? 这涉及到所谓的“生日攻击”,而生日攻击又是指“生日悖论”,它指出,当你从一个给定的集合中随机select,你需要惊讶地select几个之前,你select了两次。 但是“惊人的less”是一个非常相对的名词。

维基百科有一个表 。 没有40个字符的散列条目。 但是对于32和48个字符的条目插值使得我们在5 * 10 22个 git提交的范围内碰撞概率为0.1%。 在你碰撞几率达到0.1%之前,那是五万亿十亿不同的承诺,或五十个Zettacommits

这些提交单独的散列的字节总和比一年内在地球上产生的所有数据要多,也就是说你需要比YouTube更快的stream出video。 祝你好运。 :d

用正确的“but”来回答这个问题是不太可能的,也没有解释为什么它不是一个问题。 如果没有真正掌握散列的真正含义,就不可能做到这一点。 这比你在CS程序中可能遇到的简单情况要复杂得多。

这里对信息论有一个基本的误解。 如果通过丢弃一些数量(即哈希)将大量的信息减less到更小的数量,将会有与数据长度直接相关的碰撞机会。 数据越短,可能就越less。 现在,绝大多数的碰撞都是乱码,使得它们更有可能发生(你永远不会检查乱码……即使是二进制图像也是有点结构的)。 最后,机会是遥远的。 为了回答你的问题,是的,git会把它们看成是一样的,改变哈希algorithm不会有什么帮助,它会进行某种“第二次检查”,但最终你会需要尽可能多的“额外检查”数据作为数据的长度是100%肯定…记住,你会99.99999 ….到一个非常长的数字位数….确定与你描述一个简单的检查。 SHA-x是密码强的散列,这意味着通常难以有意地创build两个彼此非常类似并且具有相同散列的源数据集。 数据中的一点变化应该在散列输出中创build多于一个(优选尽可能多)的变化位,这也意味着从散列回到完整的集合是非常困难的(但不是完全不可能的)碰撞,从而从这组冲突中提取出原始信息 – 除了less数几个将是胡言乱语,如果信息长度很长,那么不存在大量的信息来筛选。 encryption哈希的缺点是,他们计算速度慢…一般来说。

那么Git是什么意思呢? 不多。 哈希函数很less完成(相对于其他所有函数),因此它们的计算惩罚总体上低于操作。 碰撞一次碰撞的几率是如此之低,这不是一个现实的机会发生,而不是立即被发现(即你的代码很可能会突然停止build设),允许用户解决问题(备份一个修订,并再次进行更改,而且几乎肯定会因为时间更改而获得不同的哈希值,这也会在git中提供哈希值)。 如果你在git中存储任意的二进制文件,那么对于你来说,更有可能成为一个真正的问题,这实际上并不是它的主要使用模式。 如果你想这样做…你可能会更好使用传统的数据库。

思考这个问题并不错 – 这是一个很好的问题,很多人只是认为“不太可能不值得去思考” – 但实际上比这更复杂一点。 如果它发生,它应该是非常容易检测到的,这不会是一个正常的工作stream程中的沉默腐败。

可以改善生活,或者我将不得不改变一个新的哈希algorithm?

任何散列algorithm都可能发生冲突,所以改变散列函数并不能排除这个问题,只是使得它不太可能发生。 所以你应该select一个非常好的散列函数(已经是SHA-1了,但你不要被告知:)

Google现在声称在某些先决条件下SHA-1可能是相互冲突的: https : //security.googleblog.com/2017/02/announcing-first-sha1-collision.html

由于git使用SHA-1来检查文件完整性,这意味着git中的文件完整性会受到影响。

海事组织,混帐应该肯定使用更好的哈希algorithm,因为故意的碰撞现在是可能的。

哈希碰撞是非常不可能的,这是纯粹的头脑吹! 世界各地的科学家都在努力实现,但还没有pipe理。 但是对于某些algorithm,比如MD5,他们成功了。

有什么可能性?

SHA-256有2 ^ 256个可能的散列。 那大约是10 ^ 78 。 或者为了更形象,碰撞的可能性大约在

1:10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

获得彩票的机会约为1:14亿 。 与SHA-256碰撞的机会就像连续11天中奖一样!

math解释: 14万000 ^ 11〜2 ^ 256

而且, 宇宙有大约10 ^ 80个primefaces。 这只是SHA-256组合的100倍。

成功的MD5碰撞

即使是MD5 ,机会也很小。 虽然,math家设法造成了碰撞:

  d131dd02c5e6eec4 693d9a0698aff95c 2fcab5 8 712467eab 4004583eb8fb7f89
 55ad340609f4b302 83e4888325 7 1415a 085125e8f7cdc99f d91dbdf280373c5b
 d8823e3156348f5b ae6dacd436c919c6 dd53e2 b 487da03fd 02396306d248cda0
 e99f33420f577ee8 ce54b67080 a 80d1e c69821bcb6a88393 96f965 2 b6ff72a70 

具有相同的MD5

  d131dd02c5e6eec4 693d9a0698aff95c 2fcab5 0 712467eab 4004583eb8fb7f89
 55ad340609f4b302 83e4888325 f 1415a 085125e8f7cdc99f d91dbd7280373c5b
 d8823e3156348f5b ae6dacd436c919c6 dd53e2 3 487da03fd 02396306d248cda0
 e99f33420f577ee8 ce54b67080 2 80d1e c69821bcb6a88393 96f965 a b6ff72a70 

这并不意味着MD5algorithm已经被破解,因此不太安全。 您可以有意识地创buildMD5冲突,但偶然发生MD5冲突的可能性仍然是2 ^ 128,这仍然很多。

结论

你不必担心碰撞。 散列algorithm是检查文件相同性的第二种最安全的方法。 唯一比较安全的方法是二进制比较。

那么我猜我们现在知道会发生什么 – 你应该期望你的仓库将被损坏( 源 )。

您可以在“ Git如何处理BL-1上的SHA-1碰撞? ”中看到一个很好的研究。

由于SHA1碰撞现在是可能的(正如我在这个答案中用shaTtered.io引用的那样),知道Git 2.13(Q2 2017)将通过SHA-1实现的“检测尝试创build冲突”来改善/减轻当前情况由Marc Stevens(CWI)和Dan Shumow(微软)提供 。

参见Jeff King( peff )的 提交f5f5e7f , 提交8325e43 , 提交c0c2006 , 提交45a574e , 提交28dc98e (2017年3月16日) 。
(由Junio C gitstergitster合并-在承诺48b3693 ,2017年3月24日)

Makefile :使DC_SHA1成为默认值

我们默认使用OpenSSL库中的SHA1实现。
由于我们正试图在最近发生的“破碎”通告之后小心处理碰撞攻击,因此请改用缺省设置以鼓励用户使用DC_SHA1实现。
那些想要使用OpenSSL实现的人可以通过OPENSSL_SHA1=YesPlease明确地要求它在运行“ make ”时请求。

我们实际上并没有发生Git对象冲突,所以我们可以做的最好的事情就是通过test-sha1运行一个破碎的PDF文件。 这应该触发碰撞检查并死亡。