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

qaz*_*wsx 77 git cryptography sha

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

sof*_*ess 50

更新:上述问题和答案均来自2015年.此后,谷歌宣布了第一次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的存储大小更大.

一些链接:

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

  • Git的哈希需要对人们在其代码上进行验证的安全签名安全.这些签名标志着这些哈希的巨大树.如果该树的某个分支发生冲突,则可以在签名通过时插入恶意代码.Git现在使用得非常广泛.需要哈希升级. (9认同)
  • "你可以让人们谁尝试是恶意的.他们是不会成功的.没有人能够打破SHA-1,但有一点是SHA-1,尽可能的Git而言,甚至不是一项安全功能这纯粹是一致性检查." -Linus Torvalds (7认同)

Von*_*onC 43

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

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

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

Git 2.16将提出一个基础结构来定义Git中使用的哈希函数,并将开始尝试在各种代码路径中进行检测.

请参阅Ramsay Jones(``)提交c250e02(2017年11月28日).
请参阅brian m的提交eb0ccfd,提交78a6766,提交f50e766,提交abade65(2017年11月12日).卡尔森(bk2204).
(由Junio C gitsterHamano合并- -提交721cc43,2017年12月13日)


添加表示哈希算法的结构

由于将来我们希望支持额外的哈希算法,添加一个表示哈希算法的结构以及必须与之一起使用的所有数据.
添加常量以便轻松枚举哈希算法.
实现函数typedefs以创建可由任何散列算法使用的抽象API,以及符合此API的现有SHA1函数的包装器.

公开十六进制大小和二进制大小的值.
虽然一个将始终是另一个的两倍,但这两个值在整个代码库中都非常普遍使用,并且两者都提供了改进的可读性.

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

当前的哈希函数转换计划设想我们将接受来自用户的输入的时间,该输入可能是SHA-1或NewHash格式.
由于我们无法知道用户提供了哪些内容,因此添加一个表示未知算法常量,以便我们指出我们必须查找正确的值.


将哈希算法支持与repo设置集成

在Git的未来版本中,我们计划支持额外的哈希算法.
将哈希算法的枚举与存储库设置集成,并在struct repository中存储指向枚举数据的指针.
当然,我们目前只支持SHA-1,所以硬编码这个值 read_repository_format.
将来,我们将从配置中枚举此值.

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


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

参见Jonathan Nieder()提交0ed8d8d(2018年8月4日). 见提交13f5e09通过(2018年7月25日)ÆvarArnfjörðBjarmason( ). (由Junio C Hamano合并- -提交34f2297,2018年8月20日)artagnon
avar
gitster

dochash-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年作为变量名称 t/t9700/test.pl的无关使用.


您可以通过Git 2.20(Q4 2018)看到正在进行到SHA 256的过渡:

提交0d7c419,提交dda6346,提交eccb5a5,提交93eb00f,提交d8a3a69,提交fbd0e37,提交f690b6b,提交49d1660,提交268babd,提交fa13080,提交7b5e614,提交58ce21b,提交2f0c9e9,提交825544a(二○一八年十月十五日)由布赖恩米.卡尔森(bk2204).
提交6afedba由(二零一八年十月十五日)SZEDER的Gabor( )szeder.
(由Junio C gitsterHamano合并- -提交d829d49,2018年10月30日)

替换硬编码常量

在适当的情况下,用引用GIT_MAX_HEXSZ或 替换几个基于40的常量替换the_hash_algo.
转换GIT_SHA1_HEXSZ要使用的所有用法,the_hash_algo以便它们适用于任何给定的哈希长度.
不使用硬编码常量作为十六进制对象ID的大小,而是切换为parse_oid_hex在解析的对象ID之后使用来自该点的计算指针.


这种转变继续使用Git 2.21(2019年第一季度),它增加了sha-256哈希并通过代码插入它以允许使用"NewHash"构建Git.

提交4b4e291,提交27dc04c,提交13eeedb,提交c166599,提交37649b7,提交a2ce0a7,提交50c817e,提交9a3a0ff,提交0dab712,提交47edb64(二○一八年十一月一十四日),以及提交2f90b9d,提交1ccf07c由(2018年10月22日)布赖恩米.卡尔森(GIT_SHA1_HEXSZ).
(由Junio C bk2204Hamano合并- -提交33e4ae9,2019年1月29日)

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

SHA-1很弱,我们需要转换到新的哈希函数.
一段时间以来,我们将这个新功能称为gitster.
最近,我们决定选择SHA-256作为NewHash.
在此线程和哈希函数转换文档的提交历史中概述了选择SHA-256的原因.

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

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

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

libtomcrypt:使用OpenSSL添加SHA-256实现

我们已经有可用于SHA-1的OpenSSL例程,因此也为SHA-256添加例程.

在Core i7-6600U上,此SHA-256实现优于SHA1DC SHA-1实现:

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)
Run Code Online (Sandbox Code Playgroud)

hash:使用添加SHA-256实现 sha256

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

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

为了进行比较,在Core i7-6600U上,此实现以355 MiB/s处理16 KiB块,而SHA1DC处理337 MiB/s的等效块.

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

  • 另外,不要忘记,Git v2.13.0 及更高版本随后默认转向强化的 SHA-1 实现,该实现不易受到 SHAttered 攻击。请参阅/sf/answers/3034914291/ (2认同)

Arn*_*ide 5

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

简而言之:如果您今天不十分勤快,则漏洞比sha1差得多。但是尽管如此,Mercurial还是在10多年前就开始准备从sha1迁移出去。

多年以来一直在努力为SHA1的后继者改造Mercurial的数据结构和协议。十多年前,随着RevlogNG的推出,我们的revlog结构中为较大的哈希分配了存储空间。最近引入的bundle2格式支持通过网络交换不同的哈希类型。剩下的剩下的就是选择替换功能和选择向后兼容策略。

如果git在Mercurial之前没有从sha1迁移过来,则始终可以通过使用hg-git保留本地Mercurial镜像来增加另一级别的安全性。