如果我在使用Git时发生哈希碰撞会发生什么?
例如,我设法提交两个具有相同sha1校验和的文件,Git会注意到它还是会损坏其中一个文件吗?
Git能否改进以处理这种情况,还是我必须更换新的哈希算法?
(请不要通过讨论这种情况有多么不可能来回避这个问题-谢谢)
如果我在使用Git时发生哈希碰撞会发生什么?
例如,我设法提交两个具有相同sha1校验和的文件,Git会注意到它还是会损坏其中一个文件吗?
Git能否改进以处理这种情况,还是我必须更换新的哈希算法?
(请不要通过讨论这种情况有多么不可能来回避这个问题-谢谢)
SHA-1哈希是一个由40个十六进制字符组成的字符串...每个字符4位,乘以40得到160位。现在我们知道10位大约等于1000(确切地说是1024),这意味着有 1 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 种不同的SHA-1哈希值...即1048。
这相当于什么?月球由大约1047个原子组成。所以,如果我们有10个卫星...并且你在其中一个卫星上随机选择一个原子...然后再随机选择一个原子...那么你两次选择同一个原子的概率,就是两个给定的git提交具有相同SHA-1哈希值的概率。
基于此,我们可以问一个问题...
在存储库中需要多少个提交才应该开始担心冲突?
这与所谓的“生日攻击”有关,它又指的是“生日悖论”或“生日问题”,即当你从一个给定的集合中随机选择时,在你选择两次之前,你需要惊人地很少的选择次数。但是,“惊人地很少”在这里是一个非常相对的术语。重点是,除非有人故意引发碰撞,否则随机发生碰撞的概率极小,您可以忽略此问题。
好的,假设不太可能发生,或者假设有人成功地定制了故意SHA-1哈希碰撞。那么接下来会发生什么?
在这种情况下,有一个很好的答案,有人对此进行了实验。我将引用该答案:
如果使用相同的哈希值已存在 blob,则您将不会收到任何警告。一切似乎都很正常,但是当您推送、克隆或还原时,您将丢失最新版本(与上面所述的相符)。正如你所看到的,有些情况并不好。特别是#2和#3这两种情况会破坏你的代码库。然而,似乎问题仅限于该代码库内部,攻击或奇怪的不可能性并不会传播到其他代码库。
此外,人为碰撞的问题被认为是一个真正的威胁,因此例如GitHub正在采取措施防止这种情况发生。
您可以在 "Git如何处理blob的SHA-1冲突?" 中看到一篇很好的研究。
由于SHA1冲突现在已经成为可能(就像我在这个答案中引用的shattered.io一样),请知道Git 2.13(2017年第二季度)将通过Marc Stevens(CWI)和Dan Shumow(Microsoft)的SHA-1实现的“检测创建冲突的尝试”变体来改善/缓解当前情况。
请查看提交 f5f5e7f, 提交 8325e43, 提交 c0c2006, 提交 45a574e, 提交 28dc98e (2017年3月16日),作者为Jeff King (peff
)。
(由Junio C Hamano -- gitster
--在提交 48b3693中合并,2017年3月24日)
Makefile
:使DC_SHA1
成为默认选项我们曾经默认使用OpenSSL库中的SHA1实现。
由于最近的“shattered”公告后,我们正在小心应对碰撞攻击,因此将默认选项更改为鼓励人们使用DC_SHA1实现。
那些想要使用OpenSSL实现的人可以在运行“make
”时通过OPENSSL_SHA1=YesPlease
明确请求。
我们实际上并没有Git对象碰撞,所以我们能做的最好的事情就是通过test-sha1运行shattered PDFs之一。 这应该触发碰撞检查并导致程序崩溃。
Git能否改进以适应此情况,还是我必须更换新的哈希算法?
2017年12月更新:随着Git 2.16(2018年第一季度)的推出,支持使用另一种哈希算法的工作正在进行中:请参见“为什么Git不使用更现代的SHA算法?”。
您将能够使用其他哈希算法:SHA1不再是Git的唯一哈希算法。
Git 2.18(2018年第二季度)记录了这个过程。
请参见提交5988eb6,提交45fa195(2018年3月26日),作者是Ævar Arnfjörð Bjarmason ( avar )
。
(由Junio C Hamano -- gitster --
合并在提交d877975中,2018年4月11日)
文档 hash-function-transition
: 澄清SHAttered的含义
尝试澄清SHAttered攻击在Git中的实际含义。
之前的版本中完全没有提到Git已经针对这种特定攻击采取了缓解措施,而SHAttered研究人员声称,这种措施将检测到密码分析碰撞攻击。
我可能有些细微之处理解不正确,但据我所知,这个新文本准确地总结了SHA-1在Git中的当前情况。也就是说,git现在不再使用SHA-1,而是使用Hardened-SHA-1(它们恰好99.99999999999...%的时间产生相同的输出)。
因此,之前的文本在断言以下内容时是不正确的:
[...]结果[SHAttered],SHA-1不能再被认为是具有密码学安全性的[...]
事实并非如此。我们已经针对SHAttered采取了缓解措施,但是如果未来SHA-1或Hardened-SHA-1出现漏洞,我们认为采取向NewHash
迁移的工作是明智的。
因此,新文档 现在的内容如下:
Git v2.13.0及以后版本默认采用了一个更加安全的SHA-1实现,不再容易受到SHAttered攻击。因此,Git已经实际上迁移到了一个新的哈希函数,它不是SHA-1并且不会共享其漏洞。它的新哈希函数恰好为所有已知输入生成完全相同的输出,除了SHAttered研究人员发布的两个PDF文件以及由这些研究人员编写的新实现声称可以检测未来的密码分析碰撞攻击。但无论如何,将任何SHA-1变体替换为新哈希算法都被认为是明智的。不能保证未来不会发生对SHA-1的攻击,并且这些攻击可能没有可行的缓解措施。如果SHA-1及其变体真的被破解,Git的哈希函数将不再被认为是加密安全的。这将影响哈希值的通信,因为我们无法相信给定的哈希值代表发言者想要表达的已知内容的正确版本。
注意:同一份文档现在(2018年第三季度,Git 2.19)明确将“新哈希”称为SHA-256:请参见“为什么Git不使用更现代的SHA?”。
Git能否改进以解决这个问题,还是我需要更换一个新的哈希算法?
任何哈希算法都有可能发生冲突,因此更改哈希函数并不能完全避免问题,只能降低发生的概率。所以你应该选择一个真正优秀的哈希函数(SHA-1已经是一个好的选择了,但你不想听这个 :))。
最近我在一个BSD讨论组中发现了一篇2013-04-29的帖子,网址为
http://openbsd-archive.7691.n7.nabble.com/Why-does-OpenBSD-use-CVS-td226952.html
在这篇文章中,作者声称:
我曾经在使用git rebase时遇到了哈希碰撞。
不幸的是,他没有提供任何证明。但也许你想尝试联系他并询问他是否真的遇到了这个问题。
但更普遍地说,由于生日攻击,SHA-1哈希碰撞的机会是pow(2,80)中的1。
这听起来很多,肯定比世界上所有Git存储库中存在的单个文件版本的总数要多得多。
然而,这仅适用于实际保留在版本历史记录中的版本。
如果开发人员非常依赖于rebase,在对分支运行rebase时,该分支(或重建的分支部分)的所有版本中的所有提交都会获得新的哈希值。对于每个使用"git filter-branch"修改的文件也是如此。因此,“rebase”和“filter-branch”可能是随着时间推移生成的哈希数量的大乘数,尽管并非所有哈希值都被实际保留:通常,在重新构建(特别是为了“清理”一个分支)之后,原始分支将被丢弃。
但是,如果在rebase或filter-branch过程中发生碰撞,它仍可能产生不良影响。
另外一件事是估计Git仓库中散列实体的总数,并查看它们与pow(2, 80)相差多少。哈希碰撞是如此不太可能发生的事情,它令人难以置信!全世界的科学家都在努力实现它,但至今未能成功。然而对于某些算法,比如MD5,他们已经成功了。
SHA-256 有2^256种可能的哈希值,大约是10^78。或者更形象地说,碰撞的概率大约是
1 : 100 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
中奖的概率大约是1 : 14百万。SHA-256发生碰撞的概率就像连续11天中彩票一样难中!
数学解释:14 000 000 ^ 11 ~ 2^256
此外,宇宙大约有10^80个原子。这只比SHA-256组合的数量多100倍。
即使对于MD5,机会也是微乎其微的。尽管如此,数学家们还是成功地创建了一次碰撞:
d131dd02c5e6eec4 693d9a0698aff95c 2fcab58712467eab 4004583eb8fb7f89 55ad340609f4b302 83e488832571415a 085125e8f7cdc99f d91dbdf280373c5b d8823e3156348f5b ae6dacd436c919c6 dd53e2b487da03fd 02396306d248cda0 e99f33420f577ee8 ce54b67080a80d1e c69821bcb6a88393 96f9652b6ff72a70
与以下文本具有相同的MD5:
d131dd02c5e6eec4 693d9a0698aff95c 2fcab50712467eab4004583eb8fb7f89 55ad340609f4b302 83e4888325f1415a085125e8f7cdc99f d91dbd7280373c5b d8823e3156348f5b ae6dacd436c919c6 dd53e23487da03fd02396306d248cda0 e99f33420f577ee8 ce54b67080280d1ec69821bcb6a88393 96f965ab6ff72a70