为什么 Git 需要签名推送

  • 本文关键字:Git git
  • 更新时间 :
  • 英文 :


在 Git 2.2.0 的发行说明中,它描述了一个新选项来git push--signed

"git push" learned "--signed" push, that allows a push (i.e.
request to update the refs on the other side to point at a new
history, together with the transmission of necessary objects) to be
signed, so that it can be verified and audited, using the GPG
signature of the person who pushed, that the tips of branches at a
public repository really point the commits the pusher wanted to,
without having to "trust" the server.

因此,听起来在推送过程中发送到服务器的数据已经过签名,以便服务器可以验证并记录谁进行了推送。 在man页面中,您可以确认这一点:

--signed
   GPG-sign the push request to update refs on the receiving side, 
   to allow it to be checked by the hooks and/or be logged. See 
   git-receive-pack[1] for the details on the receiving end.

您可以在man页面中查找pre-receivepost-recieve钩子下的git-receive-pack,以准确了解如何验证签名推送。

似乎所有这些都有助于服务器验证谁在做推送,他们到底是谁。

git push --signed如何帮助您(推送者(不必"信任"服务器? 到目前为止,我所看到的一切似乎都表明它有助于服务器信任您。 更重要的是,为什么签名提交和签名标签不足以推送到不受信任的服务器?为什么我们甚至需要签名推送?

以下是引入签名推送的提交消息的摘录:

而签名标记和提交断言这样签名的对象 来自你,谁签了这些东西,没有一个好办法 断言您希望在 特定分支。 我的签名 v2.0.1 标签仅表示我想调用 版本v2.0.1,这并不意味着我想将其推送到我的 "主"分支---很可能我只想在"维护"中使用它,所以 仅对象上的签名是不够的。

对你的唯一保证是"维护"指向我想要的东西 那里的地方来自您对托管站点的信任和我的 使用它进行身份验证,以后无法轻松审核。

因此,即使提交已签名,您也无法确定作者是否打算将该提交推送到分支master或分支super-experimental-feature。 签名推送允许服务器保留每个推送事件及其签名的记录。 然后可以验证此日志,以查看每个提交确实打算在特定分支上。

最初的讨论在这里,对于 Git 2.2(Q4 2014(.
它包括:

每一行在此推送尝试更新的 ref 的尖端显示旧对象名称和新对象名称,其方式与底层"git push"协议交换告诉 ref 更新到接收端的方式相同(通过记录"旧"对象名称,推送证书还可以防止重放(。

它还记录了推送的

预期收件人的 URL(如果有身份验证材料,则匿名化后(在新的"推送者"上网址"标头。此值可能无法可靠地用于重放攻击预防目的,但这仍将用作人类可读的提示,以标识证书引用的存储库。

为了防止用于推送到存储库的有效推送证书被重放以推送到不相关的存储库,请从接收包进程发送随机数字符串,并让签名者将其包含在推送证书中><。接收端使用其服务的存储库路径和当前时间的 HMAC 哈希,并使用密钥进行哈希处理(这不必是每个存储库,但可以在 /etc/gitconfig 中定义(,以确保随机第三方无法伪造看起来像是源自它的随机数。

<小时 />

自 Git 2.2 (2014( 以来,最近的补丁突出了上面提到的"提交重放预防技术":

虽然签名推送

确实允许服务器记录每个推送事件及其签名,但在 Git 2.19(2018 年第 3 季度(之前,它可能无法记录正确的用户:

"git send-pack --signed"(因此"git push --signed"通过HTTP传输(没有从配置机制中读取用户标识来确定将推送证书签名为谁,这已被更正。

参见提交 d067d98 (2018 年 6 月 12 日( by Masaya Suzuki ( draftcode (.
(由Junio C Hamano -- gitster -- 在提交 8d3661d 中合并,2018 年 6 月 28 日(

builtin/send-pack:填充默认配置

builtin/send-pack没有打电话给git_default_config,正因为如此 git push --signed不尊重用户名和电子邮件 gitconfigHTTP 传输。

<小时 />

在 Git 2.27(2020 年第 2 季度(中,推送证书的验证针对定时攻击变得更加可靠。

参见提交 719483e (2020 年 4 月 22 日( 由 Junio C Hamano ( gitster (.
参见提交 edc6dcc (09 Apr 2020( by Brian M. Carlson ( bk2204 (.
(由Junio C Hamano -- gitster -- 在提交 2abd648 中合并,2020 年 4 月 28 日(

builtin/receive-pack:对HMAC值使用常量时间比较

签名者:布莱恩·卡尔森

当我们比较推送证书随机数时,我们目前使用 .大多数实现strcmp短路,一旦知道两个值是否相等,就会退出

然而,当我们比较 HMAC 的输出时,这是一个问题,因为它会在花费的时间内泄漏有关两个值中有多少匹配的信息(如果它们确实不同(。

在我们的例子中,nonce用于防止通过嵌入式时间戳对我们服务器的重放攻击,以及通过HMAC使用来自不同服务器的请求进行重放攻击。

包含随机数

的推送证书已签名,因此攻击者无法在不破坏签名验证的情况下篡改随机数。

当然,他们可以使用无效的随机数创建自己的签名,但他们也可以使用有效的随机数创建自己的签名,因此没有任何好处。

因此,不存在安全问题。

尽管当前技术似乎没有任何负面影响,但为了安全和鼓励良好实践,让我们使用恒定时间比较函数进行随机数验证。POSIX没有提供,但它们很容易编写。

我们在这里使用的技术也用于 NaCl 和 Go 标准库,并且依赖于按位或和异或在所有已知架构上都是常量时间的事实。

如果实际长度和预期长度不同,我们不必担心提前退出,因为标准的加密假设是每个人,包括攻击者,都知道我们的随机数中使用的格式和算法(无论如何,他们有源代码并且可以轻松确定它(。

因此,我们假设每个人都知道我们的随机数应该有多长。

Go 标准库和其他加密库在对 HMAC 值执行恒定时间比较时也采用了这一理念。

简短的回答是,git push --signed的目的是防止提交重放攻击。

如果您将未经测试/不安全代码的签名提交推送到分支experimental则其他人可以将该提交重播到master分支,即使您从未打算将该代码推送到分支master它仍然显示为由您签名。

相关内容

  • 没有找到相关文章

最新更新