为什么Git不使用更现代的SHA?

时间:2015-01-26 21:28:08

标签: git cryptography sha

我读到Git使用SHA-1摘要作为修订版的ID。为什么不使用更现代的SHA版本?

4 个答案:

答案 0 :(得分:50)

更新:上述问题及此答案均来自2015年。此后,Google宣布首次发生SHA-1碰撞:https://security.googleblog.com/2017/02/announcing-first-sha1-collision.html


显然我只能从外面猜测为什么Git继续使用SHA-1,但这些可能是原因之一:

  1. Git是Linus Torvald的创作,而Linus显然不想在此时用另一种哈希算法替换SHA-1。
  2. 他提出合理的说法,即成功的基于SHA-1碰撞的攻击对Git的攻击比实现碰撞本身要困难得多,并且考虑到SHA-1比它应该的更弱,而不是完全被破坏,这使得它显着至少在今天,它远非可行的攻击。此外,他指出,如果碰撞对象比现有碰撞对象迟到,那么“成功”攻击将获得很少,因为后者将被假定为与有效对象相同而被忽略(尽管其他人已指出反过来可能会发生。)
  3. 更改软件非常耗时且容易出错,尤其是在现有基础架构和基于现有协议的数据必须迁移的情况下。即使那些生产加密安全性是系统唯一点的软件和硬件产品的人仍然在远离SHA-1和其他弱算法的过程中。想象一下所有那些硬编码的unsigned char[20]缓冲区;-),在开始时为加密敏捷性编程要容易得多,而不是在以后对其进行改造。
  4. SHA-1的性能优于各种SHA-2哈希(可能不是现在的交易破坏者,但可能是10年前的一个难点),以及SHA的存储大小2更大。
  5. 一些链接:

    我的个人观点是,虽然实际攻击可能需要一段时间,但即使它们确实发生了,人们最初可能会通过改变哈希算法本身以外的手段来减轻它们,如果您确实关心安全性,那么你应该谨慎选择算法,并不断修改你的安全优势,因为攻击者的能力也只是向一个方向发展,所以把Git作为一个榜样是不明智的,特别是它使用SHA-1的目的并不是加密安全性。

答案 1 :(得分:34)

  

为什么不使用更现代的SHA版本?

十二月2017年:会的。 Git 2.16(2018年第一季度)是第一个用于说明和实现该意图的版本。

注意:请参阅下面的Git 2.19:它将是 SHA-256

Git 2.16将提出一个基础结构来定义Git中使用的哈希函数,并将开始在各种代码路径中探测它。

commit c250e02Ramsay Jones (``)(2017年11月28日) 请commit eb0ccfd查看commit 78a6766commit f50e766commit abade65brian m. carlson (bk2204)(2017年11月12日)。 (由Junio C Hamano -- gitster --合并于commit 721cc43,2017年12月13日)

  

添加表示哈希算法的结构

     

由于将来我们希望支持其他哈希算法,请添加 a structure that represents a hash algorithm and all the data that must go along with it
  添加constant to allow easy enumeration of hash algorithms
  实现function typedefs以创建可由任何哈希算法使用的抽象API,以及符合此API的现有SHA1函数的包装器。

     

公开value for hex size as well as binary size
  虽然一个将始终是另一个的两倍,但这两个值都非常有用   通常在整个代码库中提供两者都可以提高可读性。

     

不要在空对象ID的哈希算法结构中包含条目   由于该值全为零,因此可以使用任何适当大小的全零对象ID,并且不需要在每个哈希的基础上存储给定的一个。

     

当前哈希函数转换计划设想我们将接受来自用户的输入的时间,该输入可能是SHA-1或NewHash格式。
  由于我们无法知道用户提供了哪些内容,因此请添加 constant representing the unknown algorithm ,以便我们指出我们必须查看正确的值。

  

将哈希算法支持与repo setup

集成      

在Git的未来版本中,我们计划支持额外的哈希   算法。
  将哈希算法的枚举与存储库设置集成,并存储指向struct repository 中的枚举数据的指针。
  当然, we currently only support SHA-1, so hard-code this value in read_repository_format   将来,我们将从配置中枚举此值。

     

添加a constant, the_hash_algo,它指向存储库全局中的hash_algo结构指针   请注意,这是用于将数据序列化到磁盘的散列,而不是用于向用户显示项目的散列。
  过渡计划预计这些可能会有所不同   我们可以在将来添加一个额外的元素(比如ui_hash_algo)来提供这种情况。

2018年8月更新,对于Git 2.19(2018年第3季度),Git似乎选择 SHA-256 作为NewHash。

commit 0ed8d8dJonathan Nieder (artagnon)(2018年8月4日) 请commit 13f5e09Ævar Arnfjörð Bjarmason (avar)(2018年7月25日) (由Junio C Hamano -- gitster --合并于commit 34f2297,2018年8月20日)

  

doc hash-function-transition:选择SHA-256作为NewHash

     

从安全角度来看,似乎SHA-256,BLAKE2,SHA3-256,K12等都被认为具有类似的安全属性。
  从安全角度来看,所有这些都是不错的选择。

     

SHA-256有许多优点:

     
      
  • 它已经存在了一段时间,被广泛使用,并且几乎每个加密库(OpenSSL,mbedTLS,CryptoNG,SecureTransport等)都支持它。

  •   
  • 当您与SHA1DC进行比较时,即使没有加速,大多数矢量化的SHA-256实现确实更快。

  •   
  • 如果我们使用OpenPGP进行签名(或者甚至,我认为,CMS),我们将会使用SHA-2,所以拥有它是没有意义的我们的安全性取决于两个独立的算法,当我们只依赖一个算法时,其中任何一个算法都会破坏安全性。

  •   
     

所以SHA-256是
  更新哈希函数转换设计文档,这样说。

     

在此修补程序之后,没有剩余的字符串实例   " NewHash",但2008年与a variable name in t/t9700/test.pl无关的使用除外。

您可以通过Git 2.20(Q4 2018)看到这种向SHA 256的过渡:

请参阅commit 0d7c419commit dda6346commit eccb5a5commit 93eb00fcommit d8a3a69commit fbd0e37commit f690b6b,{{3} },commit 49d1660commit 268babdcommit fa13080commit 7b5e614commit 58ce21bcommit 2f0c9e9(2018年10月15日)commit 825544a。<登记/> brian m. carlson (bk2204)commit 6afedba(2018年10月15日) (由SZEDER Gábor (szeder)合并于Junio C Hamano -- gitster --,2018年10月30日)

  

替换硬编码常量

     

使用对GIT_MAX_HEXSZthe_hash_algo的引用替换几个基于40的常量   GIT_SHA1_HEXSZ,视情况而定   转换the_hash_algo的所有用途以使用parse_oid_hex以便它们   适用于任何给定的哈希长度   而不是使用硬编码常量作为十六进制对象ID的大小,   切换到使用指向后面的GIT_SHA1_HEXSZ的计算指针   解析的对象ID。

NewHash进一步删除/替换为Git 2.22(2019年第二季度)和commit d829d49

转换继续进行Git 2.21(2019年第一季度),它增加了sha-256哈希并通过代码插入它以允许使用&#34; NewHash&#34;来构建Git。

请参阅commit d4e568bcommit 4b4e291commit 27dc04ccommit 13eeedbcommit c166599commit 37649b7commit a2ce0a7,{{3} } {,commit 50c817ecommit 9a3a0ff(2018年11月14日)和commit 0dab712commit 47edb64(2018年10月22日)commit 2f90b9d
(由commit 1ccf07c合并于brian m. carlson (bk2204),2019年1月29日)

  

添加SHA-256支持的基本实现(2019年2月)

     

SHA-1很弱,我们需要转换到新的哈希函数   有一段时间,我们将此新功能称为 NewHash   最近,我们决定选择SHA-256作为libtomcrypt   Junio C Hamano -- gitster --以及哈希函数转换文档的提交历史记录。

     

根据 hash 添加SHA-256的基本实现,该实现位于   公共领域   对其进行优化并对其进行重组以符合我们的编码标准   从SHA-1块实现中提取更新和最终函数,因为我们知道这些函数与所有编译器一起正确运行。此实现比SHA-1慢,但在将来的提交中将引入更多高性能的实现。

     

在哈希算法列表中连接SHA-256,并添加一个测试   算法正常工作。

     

请注意,使用此补丁时,仍然无法在Git中切换到使用SHA-256   需要额外的补丁来准备代码以处理更大的散列算法,并且需要进一步的测试修复。

     

SHA-1: 157 MiB/s (64 byte chunks); 337 MiB/s (16 KiB chunks) SHA-256: 165 MiB/s (64 byte chunks); 408 MiB/s (16 KiB chunks) :使用OpenSSL

添加SHA-256实现      

我们已经有可用于SHA-1的OpenSSL例程,因此添加例程   对于SHA-256也是如此。

     

在Core i7-6600U上,这个SHA-256实现比较有利   SHA1DC SHA-1实现:

sha256
     

libgcrypt:使用libgcrypt

添加SHA-256实现      

通常,使用汇编语言编写的加密例程比C语言更好,SHA-256也是如此。
  此外,大多数Linux发行版都无法分发Git链接   OpenSSL是出于许可的原因。

     

大多数使用GnuPG的系统也会有libgcrypt,因为它是GnuPG的依赖。
  对于少量KiB和更大的消息,{{1}}也比SHA1DC实现更快。

     

为了进行比较,在Core i7-6600U上,此实现处理16 KiB   块速率为355 MiB / s,而SHA1DC处理相当于337的块   MIB /秒。

     

此外,libgcrypt是根据LGPL 2.1获得许可的   与GPL兼容。添加使用的SHA-256实现   libgcrypt。

答案 2 :(得分:4)

这是关于从Mercurial迁移SHA1的紧迫性的讨论,但它也适用于Git:https://www.mercurial-scm.org/wiki/mpm/SHA1

简而言之:如果你今天不是非常愚蠢,那么你的漏洞就会比sha1更糟糕。但尽管如此,Mercurial还是在10多年前开始准备从sha1迁移出去。

  多年来,为SHA1的继任者改进Mercurial的数据结构和协议已经开展了多年的工作。 10年前,在Mercurial 0.9中,随着RevlogNG的引入,存储空间被分配给我们的revlog结构中的更大的哈希值。最近引入的bundle2格式支持通过网络交换不同的散列类型。剩下的唯一部分是选择替换功能并选择向后兼容策略。

如果git在Mercurial之前没有从sha1迁移,您可以通过将本地Mercurial镜像保留为hg-git来添加另一级别的安全性。

答案 3 :(得分:3)

现在有一个更强的哈希transition plan,所以看起来将来它会使用比SHA-1更现代的哈希。来自current transition plan

  

正在考虑的一些哈希值是SHA-256,SHA-512/256,SHA-256x16,K12和BLAKE2bp-256