git - 新发现的 SHA-1 冲突如何影响 Git?

标签 git sha1

最近,一组研究人员生成了两个具有相同 SHA-1 哈希 (https://shattered.it/) 的文件。

由于 Git 将此哈希用于其内部存储,这种攻击对 Git 的影响有多大?

最佳答案

编辑,2017 年 12 月下旬:Git version 2.16 is gradually acquiring internal interfaces to allow for different hashes .还有很长的路要走。


简短(但不令人满意)的回答是示例文件对 Git 来说不是问题——但两个其他(经过仔细计算)文件可能是。

我下载了这两个文件,shattered-1.pdfshattered-2.pdf,并将它们放入一个新的空存储库中:

macbook$ shasum shattered-*
38762cf7f55934b34d179ae6a4c80cadccbb7f0a  shattered-1.pdf
38762cf7f55934b34d179ae6a4c80cadccbb7f0a  shattered-2.pdf
macbook$ cmp shattered-*
shattered-1.pdf shattered-2.pdf differ: char 193, line 8
macbook$ git init
Initialized empty Git repository in .../tmp/.git/
macbook$ git add shattered-1.pdf 
macbook$ git add shattered-2.pdf 
macbook$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   shattered-1.pdf
    new file:   shattered-2.pdf

即使这两个文件具有相同的 SHA-1 校验和(并且显示基本相同,尽管一个具有红色背景而另一个具有蓝色背景),它们得到不同的 Git 哈希值:

macbook$ git ls-files --stage
100644 ba9aaa145ccd24ef760cf31c74d8f7ca1a2e47b0 0   shattered-1.pdf
100644 b621eeccd5c7edac9b7dcba35a8d5afd075e24f2 0   shattered-2.pdf

存储在 Git 中的文件有两个 SHA-1 校验和:一个是 ba9aa...,另一个是 b621e... 38762c... 也不是。但是——为什么?

答案是 Git 存储文件,不是作为它们本身,而是作为字符串文字 blob、一个空白、十进制化的文件大小、一个 ASCII NUL 字节,以及 然后是文件数据。两个文件的大小完全相同:

macbook$ ls -l shattered-?.pdf
...  422435 Feb 24 00:55 shattered-1.pdf
...  422435 Feb 24 00:55 shattered-2.pdf

因此两者都以文字文本 blob 422435\0 为前缀(其中 \0 表示单个字节,字符串中的 la C 或 Python 八进制转义符)。

如果您对 SHA-1 的计算方式一无所知,也许会感到惊讶——或者您不会感到惊讶——将相同的前缀添加到两个不同的文件中,而这两个文件之前仍然生成了相同的校验和 ,导致它们现在产生不同的校验和。

这应该变得不足为奇的原因是,如果最终校验和结果位置以及每个输入位的值非常敏感,它通过采用已知的输入文件并仅重新安排其某些位,很容易按需产生冲突。尽管在 char 193, line 8 处有不同的字节,但这两个输入文件产生相同的总和,但根据研究人员的说法,这个结果是通过尝试超过 9 个 quintillion (short scale) 输入来实现的。为了得到这个结果,他们将精心挑选的原始数据 block 放在他们控制的位置,这会影响总和,直到他们找到导致冲突的输入对。

通过添加 blob header ,Git 移动了位置,在一次或多或少的意外打嗝中破坏了 110 GPU 年的计算。

现在,知道 Git 会执行此操作,他们可以重复他们 110 GPU 年的计算,输入以 blob 422435\0 开头(前提是他们的牺牲 block 不会被推得太多;实际需要的 GPU 年计算量可能会有所不同,因为这个过程有点 stochastic )。然后他们会想出两个不同的文件,可以去掉blob header 。这两个文件现在将具有彼此不同的 SHA-1 校验和,但是当 git add-ed 时,两者将产生相同的 SHA-1 校验和。

在那种特殊情况下,第一个添加的文件将“赢得”插槽。 (假设它被命名为 shattered-3.pdf。)一个足够好的 Git——我完全不确定当前的 Git 是否这么好;见Ruben's experiment-based answerHow would Git handle a SHA-1 collision on a blob? — 会注意到 git add shattered-4.pdf,试图添加第二个文件,与第一个但不同的 shattered-3.pdf 发生冲突,并会警告你并使 git add 步骤失败。在任何情况下,您都无法将这两个文件添加到一个存储库中。

但首先,必须有人花费更多的时间和金钱来计算新的哈希冲突。

关于git - 新发现的 SHA-1 冲突如何影响 Git?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42433126/

相关文章:

git - git repo 是否应该包含部署所需的所有二进制和静态文件?

git - 在 Visual Studio 中使用 Git 时出现 "Conflicts prevent checkout"错误

c++ - SHA-1 的 C++ 实现中的错误散列

android - Google App Engine 教程,无法获取签名证书指纹(SHA1)

windows - 在 Windows 上通过 node.js 执行 git cmd 失败并出现错误

git - 如何在 PhpStorm 中查看所有 git 命令?

Java SHA1withDSA 到 PHP,可转换吗?

cryptography - 使用 HMAC SHA-1 的 PBKDF2 如何返回超过 20 个字节?

git - 如何 stash 我之前的提交?

.net - 使用 ASP.NET Core 计算 SHA1