已更新
我在StackExchange代码审查站点上使用了StackExchange。
我最初的问题是--有什么方法可以用X.509证书和时间戳?来签署Git提交吗?有一段时间,我以为我只能得到我用X.509证书签名的东西,它是由一个可信的第三方加盖时间戳的。事实并非如此。使用X.509证书的数字签名和可信的时间戳是相互排斥的。我已更新了我的问题,以反映这一点。
正如VonC所指出的,用X.509证书对Git提交进行签名并不会增加任何价值。使用GPG键是一个更好的选择,因为Git是在支持中构建的。
我接受了格雷格的回答,因为这是我所要求的最接近的答案,尽管我最初的问题有点含糊不清。正如Greg所指出的那样,如果您能够证明您在某个时间点知道了提交哈希,这就保证您知道该哈希在当时用于存储库的内容,并且不需要在存储库中存储任何额外的数据。时间戳数据可以存储在任何地方。
可以使用openssl (v1.0.0+)和curl请求提交散列的RFC3161时间戳。
请求时间戳
您需要了解一些有关此的信息:
CONTENT_TYPE="Content-Type: application/timestamp-query"
ACCEPT_TYPE="Accept: application/timestamp-reply"
openssl ts -query -cert -digest "$REV" -sha1 \
| curl -s -H "$CONTENT_TYPE" -H "$ACCEPT_TYPE" --data-binary @- $URL上面的内容将把签名的时间戳输出到stdout。如果时间戳服务拒绝请求,它还可能输出错误。
验证时间戳
这非常类似于请求时间戳,但您还需要:
时间戳服务应该使用由受信任的机构颁发的证书对时间戳进行签名。否则,你的时间戳就不会有多大的可信度。如果无法找到或创建正确的证书链,请尝试使用由cacert.pem发布的curl。我是这里。
下面的代码段假设将向stdin传递一个现有的、签名的时间戳回复。应该可以将上面的请求直接输送到下面的验证命令中。如果将来自请求的响应存储在变量中,则可能需要对其进行base64编码/解码(man base64)。
openssl ts -verify -digest "$REV" -in /dev/stdin -CAfile "$CAFILE"如果您检查一个答复,您将注意到请求摘要与所使用的Git修订相匹配。您可以使用此命令检查回复的纯文本版本。
openssl ts -reply -in /dev/stdin -text这里是一个回复的例子,我在上面添加了Git修订版。
--------------------------------------------------------------------------------
Revision: 871d715e5c072b1fbfacecc986f678214fa0b585
--------------------------------------------------------------------------------
Status info:
Status: Granted.
Status description: unspecified
Failure info: unspecified
TST info:
Version: 1
Policy OID: 1.3.6.1.4.1.6449.2.1.1
Hash Algorithm: sha1
Message data:
0000 - 87 1d 71 5e 5c 07 2b 1f-bf ac ec c9 86 f6 78 21 ..q^\.+.......x!
0010 - 4f a0 b5 85 O...
Serial number: 0xB2EA9485C1AFF55C6FFEDC0491F257C8393DB5DC
Time stamp: Aug 15 08:41:48 2012 GMT
Accuracy: unspecified
Ordering: no
Nonce: 0x615F0BF6FCBBFE23
TSA: DirName:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO Time Stamping Signer
Extensions:其他备注
许多时间戳服务要求用户在脚本签名请求中添加延迟。确保您确定您计划使用的服务是否需要它。在编写本文时,我使用的是Comodo,它要求脚本请求之间延迟15秒。我选择使用Comodo的唯一原因是因为我是从他那里购买代码签名证书的。
Git便条似乎是存储签名时间戳回复的明显选择,但我没有完全的解决方案可供发布。我现在被困在这上了。
我最初的问题和更新如下。
我希望能够在Git提交发生时证明,并且我的存储库的历史还没有被重写。不一定每次都有。一天一次或一周一次就足够了。有没有推荐的方法来做到这一点?
我知道我可以用GPG密钥来签署Git提交,但是我想知道是否有一种方法,我可以用X.509证书来签署我的提交,以及使用像http://timestamp.comodoca.com/rfc3161这样的在线时间戳服务。
如果没有,是否每天将使用git rev-parse --verify HEAD的当前版本转储到文本文件中一次,对该文件进行签名,并提交是否足以证明(大致上)在编写代码时?
为清晰的添加了信息
我知道Git保证了存储库的完整性,但据我所知,如果我控制存储库,第三方将不得不相信,我没有重写存储库的历史,也没有回滚我的时钟,创建了一个完全假的存储库,仅仅是为了“证明”我的代码比实际代码更老?我也不想公开发布我的存储库。
这里有一个虚构的用例,它应该让我更好地了解我想要做的事情。
我在网上发布了一些代码。一年后,有人在一本书或一篇文章中复制和发布相同的代码,并声称是我复制了它们。在这一点上,我希望能够获得我的存储库,并证明我在一年前,在代码重新发布之前提交了该代码。
通过使用带有时间戳服务的X.509证书,我可以在进行签名时证明。只要我能证明我知道一年前提交的散列,Git就保证了归档的完整性。
或者,是否有一种方法可以使用GPG密钥来签署提交,但是有一个经过验证的时间戳?是否有一个可信的第三方提供类似于X.509证书的时间戳服务,但用于GPG?
也许我可以使用GPG密钥和X.509证书的组合。假设我将我的(公共) GPG密钥的副本保存在存储库中,那么如果我每天结束时都这样做,下面的工作会不会进行呢?
发布于 2012-08-17 08:30:10
您所要做的就是公开发布SHA1 (提交id)。如果您愿意的话,您可以使用X.509证书(使用适当的时间戳服务)对SHA1进行签名,并将其保持不变。如果有人质疑您的作者身份,您可以很容易地显示您在生成特定SHA1的特定时间知道存储库的内容。实际上,您不需要在代码存储库中存储任何签名。
发布于 2012-08-11 22:09:05
只需在最近的提交中添加时间戳证书即可。sha1将验证证书没有被修改,证书本身将验证它声称的所有“事实”,例如来自受信任服务器的日期和时间戳,以及您声称是谁等。也就是说,提交将签署证书,正如VonC从Linus的演讲中引用的那样;-)
编辑显然需要发布新提交的sha1,否则您可以修改它(和证书),并使用新的sha1来声明新提交历史中的任何内容。与往常一样,它正在建立相互信任的网络。
发布于 2012-08-11 20:03:48
我不是我跟随的人,因为莱纳斯在制作Git时确实考虑到了这个特定的特性(即你所投入的东西的完整性正是结果)。
参见is 2007年谷歌演讲 (文字记录):
他们中的大多数我甚至不用尝试就可以放弃。
坦白地说,这几乎把外面的一切都搞定了。
有许多SCM系统不能保证您从它中获得的是您所投入的相同的东西。
如果您有内存损坏,如果您有磁盘损坏,您可能永远不会知道。
您知道的唯一方法是在检查文件时注意到文件中存在腐败现象。而且源代码管理系统根本没有保护您。
这也并不少见。这是非常普遍的。。
因此,我不认为添加另一个完整性功能会增加任何价值。
而且,“时间戳”也不是一个好主意,因为它们最初不是为DVCS录制的(参见"Git:用原始创建/修改时间戳签出旧文件“和"git的使用提交时间是多少?")。
https://stackoverflow.com/questions/11913228
复制相似问题