为什么 Git 使用密码杂凑函数?

为什么 Git 使用密码杂凑函数 SHA-1,而不是更快的非加密散列函数?

相关问题:

Stack Overflow 问题 为什么 Git 使用 SHA-1作为版本号询问为什么 Git 在提交时使用 SHA-1而不是连续数字。

34847 次浏览

极低密度辐射;


你可以从 Linus Torvalds 本人在2007年将 Git 展示给 Google上查看:
(强调我的)

我们检查被认为是加密安全的校验和。没有人能够破解 SHA-1,但关键是,就 git 而言,SHA-1甚至不是一个安全特性,它只是一个一致性检查
安全部分在别处。许多人认为,由于 git 使用 SHA-1,而 SHA-1用于加密安全的东西,因此他们认为这是一个巨大的安全特性。这跟安全没有任何关系,这是你能得到的最好的大麻。

拥有一个好的哈希对于信任你的数据 是有好处的,它碰巧还有其他一些好的特性,这意味着当我们哈希对象时,我们知道哈希是良好分布的,我们不必担心某些分布问题。

在内部,它意味着从实现的角度来看,我们可以相信散列非常好,我们可以使用散列算法,并且知道没有坏的情况。

因此,也有一些理由喜欢加密方面,但它实际上是关于信任您的数据的能力。
我向你保证,如果你把你的数据放在 git 中,你可以相信这个事实,五年后,当它从你的硬盘转换成 DVD 到任何新的技术,你复制了它,五年后你可以验证你得到的数据和你输入的数据是完全一样的。而这正是你真正应该在源代码管理系统中寻找的东西


2017年12月 Git 2.16更新(2018年第一季度) : 支持替代 SHA 的努力正在进行中: 见“ 为什么 Git 不使用更现代的 SHA?”。


我在“ Git 如何处理 SHA-1碰撞?”中提到,您的 可以工程师提交了一个特定的 SHA1 前缀(仍然是一个非常昂贵的努力)。
但正如 Eric Sink在“ Git: 加密哈希”(版本控制实例(2011):

相当重要的是,DVCS 永远不会遇到具有相同摘要的两个不同数据片段。幸运的是,良好的加密散列函数的设计使这种冲突极不可能发生。

很难找到低碰撞率的 良好的非加密散列,除非你考虑像“ 用遗传程序设计寻找最新的非加密散列”这样的研究。

您还可以阅读“ 考虑使用非加密哈希算法来提高哈希速度”,其中提到例如“ < strong > xxhash ”,一种非常快的非加密哈希算法,其工作速度接近 RAM 限制。


有关在 Git 中更改散列的讨论并不新鲜:

(Linus Torvalds)

没有什么真正的 剩下的的 mozilla 代码,但嘿,我从它开始。现在回想起来,我可能应该从已经理智地完成阻塞的 PPC 代码开始——但那是“20/20事后诸葛亮”之类的事情。

另外,嘿,mozilla 代码是一堆可怕的垃圾,这就是为什么我如此确信我可以改进的东西。所以这就是它的一种来源,即使它更多的是关于激励方面而不是任何实际的剩余代码;)

你要小心 如何衡量实际的优化收益

(Linus Torvalds)

我几乎可以向您保证,它的改进仅仅是因为它使 gcc 生成了垃圾代码,从而隐藏了一些 P4问题。

(约翰 Tapsell-johnflux)

将 git 从 SHA-1升级到新算法的工程成本要高得多。我不知道怎样才能做好。

首先,我们可能需要部署一个版本的 git (在这个对话中我们称之为版本2) ,它允许有一个插槽用于新的散列值,即使它不读取或使用该空间——它只使用位于另一个插槽中的 SHA-1散列值。

这样,一旦我们 最终部署了更新版本的 git,我们就称之为版本3,它除了生成 SHA-1散列之外,还生成 SHA-3散列,使用 git 版本2的人将能够继续进行互操作。
(虽然,根据这个讨论,它们可能是脆弱的,而那些依赖它们的仅 SHA-1补丁的人可能是脆弱的。)

简而言之,切换到 任何散列并不容易。


2017年2月更新: 是的,理论上计算碰撞 SHA1: 破碎是可能的

GIT 是如何受到影响的?

GIT 强烈依赖 SHA-1来识别和检查所有文件对象和提交的完整性。
基本上可以创建两个具有相同头提交散列和不同内容的 GIT 存储库,比如一个良性源代码和一个后门源代码。
攻击者可能有选择性地向目标用户提供任何一个存储库,这将需要攻击者计算自己的冲突。

但是:

这次攻击需要超过9,223,372,036,854,775,808次 SHA1计算。这相当于6500年的单 CPU 计算和110年的单 GPU 计算的处理能力。

所以我们先别慌。
详情请看“ Git 如何处理 blob 上的 SHA-1冲突”。