问题描述
我了解到 Git 使用 SHA-1 摘要作为修订的 ID.为什么它不使用更现代的 SHA 版本?
十二月.2017:会的.Git 2.16(2018 年第一季度)是第一个说明和实现这一意图的版本.
注意:请参阅下面的 Git 2.19:它将是 SHA-256.
Git 2.16 将提出一个基础架构来定义在 Git 中使用什么哈希函数,并将开始努力在各种代码路径中进行探测.
参见 commit c250e02(2017 年 11 月 28 日),作者为 拉姆齐·琼斯 (``).
请参阅 提交 eb0ccfd,commit 78a6766,a>,提交 abade65(2017 年 11 月 12 日)作者:布赖恩米.卡尔森 (bk2204
).
添加表示哈希算法的结构
由于将来我们要支持额外的哈希算法,添加 一种结构,表示哈希算法和所有必须与之相伴的数据.
添加一个常量以便轻松枚举哈希算法.
实现函数typedefs
到创建一个可供任何哈希算法使用的抽象 API,以及符合该 API 的现有 SHA1 函数的包装器.
公开 十六进制大小和二进制大小的值.
虽然一个永远是另一个的两倍,但这两个值都非常使用普遍存在于整个代码库中,同时提供这两种方法可以提高可读性.
不要在空对象 ID 的哈希算法结构中包含条目.
由于此值全为零,因此可以使用任何大小合适的全零对象 ID,并且无需在每个哈希的基础上存储给定的 ID.
当前的哈希函数转换计划设想我们将接受来自用户的输入,该输入可能采用 SHA-1 或 NewHash 格式.
由于我们无法知道用户提供了哪个,请添加 表示未知算法的常量,以允许我们指示我们必须查找正确的值.
将哈希算法支持与 repo 设置集成
在未来的 Git 版本中,我们计划支持额外的哈希算法.
将哈希算法的枚举与存储库设置相结合,并在结构存储库中存储指向枚举数据的指针.
当然,我们目前只支持SHA-1,所以将此值硬编码在read_repository_format
.
以后,我们会从配置中枚举这个值.
添加 一个常量,the_hash_algo
,它指向存储库全局中的 hash_algo
结构指针.
请注意,这是用于将数据序列化到磁盘的哈希值,而不是用于向用户显示项目的哈希值.
过渡计划预计这些可能会有所不同.
我们可以在未来添加一个额外的元素(例如,ui_hash_algo
)来提供这种情况.
2018 年 8 月更新,对于 Git 2.19(2018 年第三季度),Git 似乎选择 SHA-256 作为 NewHash.
参见 commit 0ed8d8d(2018 年 8 月 4 日),作者为 Jonathan Nieder (artagnon
).
请参阅 commit 13f5e09(2018 年 7 月 25 日)作者 Ævar Arnfjörð Bjarmason (avar
).
doc hash-function-过渡
:选择 SHA-256 作为 NewHash
从安全角度来看,似乎 SHA-256、BLAKE2、SHA3-256、K12 等都被认为具有相似的安全属性.
从安全的角度来看,所有这些都是不错的选择.
SHA-256 有很多优点:
它已经存在了一段时间,被广泛使用,几乎每个加密库(OpenSSL、mbedTLS、CryptoNG、SecureTransport 等)都支持它.
与 SHA1DC 相比,大多数矢量化 SHA-256 实现确实更快,即使没有加速.
如果我们使用 OpenPGP(甚至,我猜是 CMS)进行签名,我们将使用 SHA-2,因此让我们的安全性依赖于两个独立的协议是没有意义的当我们可以只依赖一个时,其中任何一个都可能破坏安全性的算法.
所以是 SHA-256.
更新 hash-function-transition 设计文档来说明.
在这个补丁之后,没有剩余的字符串实例NewHash
",除了 2008 年的不相关用途,如 变量名在t/t9700/test.pl
.
您可以通过 Git 2.20(2018 年第四季度)看到向 SHA 256 的过渡:
参见 commit 0d7c419,提交 dda6346, ,提交 93eb00f,commit d8a3a69, 提交 fbd0e37, 提交 f690b6b, 提交 49d1660, 提交 268babd, 提交 fa13080, 提交 7b5e614, 提交 58ce21b, 提交 2f0c9e9,提交 825544a(2018 年 10 月 15 日)布莱恩米.卡尔森 (bk2204
).
请参阅 commit 6afedba(2018 年 10 月 15 日),作者为 SZEDER Gábor (szeder
).
替换硬编码常量
将几个基于 40 的常量替换为对 GIT_MAX_HEXSZ
的引用或the_hash_algo
,视情况而定.
将 GIT_SHA1_HEXSZ
的所有用途转换为使用 the_hash_algo
以便它们适用于任何给定的哈希长度.
而不是使用硬编码常量来表示十六进制对象 ID 的大小,切换到使用来自 parse_oid_hex
的计算指针,该指针指向解析后的对象 ID.
GIT_SHA1_HEXSZ
进一步删除/替换为 Git 2.22(2019 年第二季度)和 提交 d4e568b.
Git 2.21(2019 年第一季度)继续这种过渡,它添加了 sha-256 哈希并将其插入代码以允许使用NewHash"构建 Git.
参见 提交 4b4e291,提交 27dc04c, ,提交 c166599,commit 37649b7, 提交 a2ce0a7, 提交 50c817e, 提交 9a3a0ff, commit 0dab712, 提交 47edb64(2018 年 11 月 14 日)和 提交 2f90b9d,提交 1ccf07c(2018 年 10 月 22 日)作者:布赖恩米.卡尔森 (bk2204
).
添加 SHA-256 支持的基本实现(2019 年 2 月)
SHA-1 很弱,我们需要转换到新的哈希函数.
一段时间以来,我们将这个新函数称为 NewHash
.
最近,我们决定选择 SHA-256 作为 NewHash
.
选择 SHA-256 的原因在此线程中进行了概述 在哈希函数转换文档的提交历史中.
添加一个基于 libtomcrypt
的 SHA-256 的基本实现,位于公有领域.
对其进行优化和重组以符合我们的编码标准.
从 SHA-1 块实现中提取更新和最终函数,因为我们在所有编译器中都正确知道这些函数.此实现比 SHA-1 慢,但会在未来的提交中引入更高性能的实现.
在哈希算法列表中连接 SHA-256,并添加一个测试算法正常工作.
请注意,使用此补丁后,仍然无法在 Git 中切换为使用 SHA-256.
需要额外的补丁来准备代码以处理更大的哈希算法,并且需要进一步的测试修复.
hash
:使用 OpenSSL 添加 SHA-256 实现
我们已经有可用于 SHA-1 的 OpenSSL 例程,因此请添加例程也适用于 SHA-256.
在 Core i7-6600U 上,此 SHA-256 实现优于SHA1DC SHA-1 实现:
SHA-1:157 MiB/s(64 字节块);337 MiB/s(16 KiB 块)SHA-256:165 MiB/s(64 字节块);408 MiB/s(16 KiB 块)
sha256
:使用 libgcrypt
添加一个 SHA-256 实现一般来说,用汇编语言编写的加密例程比 C 语言获得更好的性能,对于 SHA-256 也是如此.
此外,大多数 Linux 发行版无法分发链接到的 Git出于许可原因的 OpenSSL.
大多数带有 GnuPG 的系统也会有 libgcrypt
,因为它是 GnuPG 的一个依赖项.libgcrypt
对于几 KiB 和更大的消息也比 SHA1DC 实现更快.
作为比较,在 Core i7-6600U 上,此实现处理 16 KiB以 355 MiB/s 的速度处理块,而 SHA1DC 以 337 处理等效块MiB/s.
此外,libgcrypt 在 LGPL 2.1 下获得许可,即与 GPL 兼容.添加一个使用 SHA-256 的实现libgcrypt.
Git 2.24(2019 年第四季度)继续升级
参见 提交 aaa95df,提交 be8e172, 3f34d70, 提交 fc06be3, 提交 69fa337, 提交 3a4d7aa, 提交 e0cb7cd, 提交 8d4d86b, 提交 f6ca67d, 提交 dd336a5, 提交 894c0f6, 提交 4439c7a, 提交 95518fa, 提交 e84f357, 提交 fe9fec4, 提交 976ff7e, 提交 703d2d4,提交 703d2d4, 提交 7962e04, brian m.卡尔森 (bk2204
).
不要使用 GIT_SHA1_HEXSZ
和硬编码常量,而是切换到使用 the_hash_algo
.
在 Git 2.26(2020 年第一季度)中,测试脚本已经为对象名称使用 SHA-256 的那一天做好了准备.
参见 提交 277eb5a,提交 44b6c05, 提交7a868c5, 提交 1b8f39f, 提交 a8c17e3,提交 8320722, 提交 74ad99b, 提交 ba1be1a, 提交 cba472d, 提交 82d5aeb, 提交 3c5e65c, commit 235d3cd, 提交 1d86c8f, 提交 525a7f1, 提交 7a1bcb2, 提交 cb78f4f, 提交 717c939, >, 提交 215b60b, brian m.卡尔森 (bk2204
).
例子:
t4204
:使哈希大小独立
使用 $OID_REGEX
代替硬编码的正则表达式.
所以,不要使用:
grep "^[a-f0-9]{40} $(git rev-parse HEAD)$" 输出
测试正在使用
grep "^$OID_REGEX $(git rev-parse HEAD)$" 输出
而 OID_REGEX
来自 commit bdee9cd(5 月 13 日)2018) by brian m.卡尔森 (bk2204
).
t/test-lib
:介绍OID_REGEX
目前我们有一个变量,$_x40,
,其中包含一个匹配完整的 40 个字符的十六进制常量的正则表达式.
但是,使用 NewHash
,我们将拥有超过 40 个字符的对象 ID.
在这种情况下,$_x40
将是一个令人困惑的名称.
创建一个 $OID_REGEX
变量,该变量将始终反映匹配适当对象 ID 的正则表达式,无论当前哈希的长度如何.
而且,还在测试中:
参见 提交 f303765,提交 edf0424, , 提交d341e08, 提交 88ed241, 提交 48c10cc, 提交 f7ae8e6, 提交 e70649b, 提交a30f93b, 提交 a79eec2, 提交 796d138, commit 417e45e, 提交 dfa5f53, 提交 f743e8f, commit 72f936b, 提交 5df0f11, 提交 07877f3,commit, 提交 7b1a182, commit 94db7e3, commit 94db7e3a>(2020 年 2 月 7 日)作者:brian m.卡尔森 (bk2204
).
t5703
:使用 SHA-256 进行测试
此测试使用长度为 40 个十六进制字符的对象 ID,当使用 SHA-256 作为哈希运行时,导致测试不仅无法通过,而且会挂起.
使用 test_oid_init
和 test_oid
将此值更改为固定的虚拟对象 ID.
此外,请确保我们使用带有字段的剪切而不是固定长度来提取适当长度的对象 ID.
一些代码路径被赋予了一个存储库实例作为在存储库中工作的参数,但将 the_repository
实例传递给了它的被调用者,这已被 Git 2.26(2020 年第一季度)(在某种程度上)清理了.
参见 提交 b98d188,提交 2dcde20, 7ad5c44, 提交 c8123e7, 提交 5ec9b8a, 提交 a651946,提交 eb999b3(2020 年 1 月 30 日)由 Matheus Tavares (matheustavares
).
sha1-file
:允许 check_object_signature()
处理任何回购
check_object_signature()
的某些调用者可以在任意存储库上工作,但存储库不会传递给此函数.相反,the_repository
始终在内部使用.
要修复可能的不一致,请允许函数接收结构存储库并让这些调用者传递正在处理的存储库.
基于:
sha1-file
:通过 git_hash_algo
到 hash_object_file()
通过引入 git_hash_algo
参数,允许 hash_object_file()
处理任意 repos.更改在其范围内具有结构存储库指针的调用者,以从所述存储库传递 git_hash_algo
.
对于所有其他调用者,请传递 the_hash_algo
,它已在 hash_object_file()
内部使用.
此功能将在以下补丁中使用,以使 check_object_signature()
能够在任意 repos 上工作(反过来,这将用于修复 object.c
:parse_object()).
I read about that Git uses SHA-1 digest as an ID for a revision. Why does it not use a more modern version of SHA?
Dec. 2017: It will. And Git 2.16 (Q1 2018) is the first release to illustrate and implement that intent.
Note: see Git 2.19 below: it will be SHA-256.
Git 2.16 will propose an infrastructure to define what hash function is used in Git, and will start an effort to plumb that throughout various codepaths.
See commit c250e02 (28 Nov 2017) by Ramsay Jones (``).
See commit eb0ccfd, commit 78a6766, commit f50e766, commit abade65 (12 Nov 2017) by brian m. carlson (bk2204
).
Update August 2018, for Git 2.19 (Q3 2018), Git seems to pick SHA-256 as NewHash.
See commit 0ed8d8d (04 Aug 2018) by Jonathan Nieder (artagnon
).
See commit 13f5e09 (25 Jul 2018) by Ævar Arnfjörð Bjarmason (avar
).
You can see this transition to SHA 256 in progress with Git 2.20 (Q4 2018):
See commit 0d7c419, commit dda6346, commit eccb5a5, commit 93eb00f, commit d8a3a69, commit fbd0e37, commit f690b6b, commit 49d1660, commit 268babd, commit fa13080, commit 7b5e614, commit 58ce21b, commit 2f0c9e9, commit 825544a (15 Oct 2018) by brian m. carlson (bk2204
).
See commit 6afedba (15 Oct 2018) by SZEDER Gábor (szeder
).
GIT_SHA1_HEXSZ
is further remove/replaced with Git 2.22 (Q2 2019) and commit d4e568b.
That transition continues with Git 2.21 (Q1 2019), which adds sha-256 hash and plug it through the code to allow building Git with the "NewHash".
See commit 4b4e291, commit 27dc04c, commit 13eeedb, commit c166599, commit 37649b7, commit a2ce0a7, commit 50c817e, commit 9a3a0ff, commit 0dab712, commit 47edb64 (14 Nov 2018), and commit 2f90b9d, commit 1ccf07c (22 Oct 2018) by brian m. carlson (bk2204
).
The upgrade effort goes on with Git 2.24 (Q4 2019)
See commit aaa95df, commit be8e172, commit 3f34d70, commit fc06be3, commit 69fa337, commit 3a4d7aa, commit e0cb7cd, commit 8d4d86b, commit f6ca67d, commit dd336a5, commit 894c0f6, commit 4439c7a, commit 95518fa, commit e84f357, commit fe9fec4, commit 976ff7e, commit 703d2d4, commit 9d958cc, commit 7962e04, commit fee4930 (18 Aug 2019) by brian m. carlson (bk2204
).
With Git 2.26 (Q1 2020), the test scripts are ready for the day when the object names will use SHA-256.
See commit 277eb5a, commit 44b6c05, commit 7a868c5, commit 1b8f39f, commit a8c17e3, commit 8320722, commit 74ad99b, commit ba1be1a, commit cba472d, commit 82d5aeb, commit 3c5e65c, commit 235d3cd, commit 1d86c8f, commit 525a7f1, commit 7a1bcb2, commit cb78f4f, commit 717c939, commit 08a9dd8, commit 215b60b, commit 194264c (21 Dec 2019) by brian m. carlson (bk2204
).
Example:
So, instead of using:
grep "^[a-f0-9]{40} $(git rev-parse HEAD)$" output
Tests are using
grep "^$OID_REGEX $(git rev-parse HEAD)$" output
And OID_REGEX
comes from commit bdee9cd (13 May 2018) by brian m. carlson (bk2204
).
And, still for tests:
See commit f303765, commit edf0424, commit 5db24dc, commit d341e08, commit 88ed241, commit 48c10cc, commit f7ae8e6, commit e70649b, commit a30f93b, commit a79eec2, commit 796d138, commit 417e45e, commit dfa5f53, commit f743e8f, commit 72f936b, commit 5df0f11, commit 07877f3, commit 6025e89, commit 7b1a182, commit 94db7e3, commit db12505 (07 Feb 2020) by brian m. carlson (bk2204
).
Some codepaths were given a repository instance as a parameter to work in the repository, but passed the_repository
instance to its callees, which has been cleaned up (somewhat) with Git 2.26 (Q1 2020).
See commit b98d188, commit 2dcde20, commit 7ad5c44, commit c8123e7, commit 5ec9b8a, commit a651946, commit eb999b3 (30 Jan 2020) by Matheus Tavares (matheustavares
).
Based on:
这篇关于为什么 Git 不使用更现代的 SHA?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!