我有posted a script我正在使用StackExchange Code Review网站。
我最初的问题是我是否可以使用X.509证书和时间戳签署Git提交?。有一段时间我以为我只能用我的X.509证书签署的东西,我的X.509证书是由受信任的第三方加上时间戳的。不是这种情况。使用X.509证书和可信时间戳进行数字签名是互斥的。我已经更新了我的问题以反映这一点。
正如VonC所指出的,签署Git提交X.509证书并不能添加任何值。使用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
。它是here。
以下代码段假定现有的签名时间戳回复正在传递给stdin
。应该可以将上述请求直接传递给下面的verify命令。如果将请求中的响应存储在变量中,则可能需要对其进行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笔记似乎是存储签名时间戳回复的明显选择,但我还没有完整的发布解决方案。我此刻被this困住了。
我的原始问题和更新如下。
我希望能够证明何时我的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密钥的副本,如果我在每天结束时执行此操作,以下工作是否会起作用?
答案 0 :(得分:3)
只需在您的最新提交中添加带时间戳的证书即可。 sha1将验证证书是否已被修改,证书本身将验证所有这些事实'它声称,例如来自可信任服务器的日期和时间戳,以及您声称是谁,等等。也就是说,提交签署证书,根据VonC引用Linus的演讲; - )
[编辑]显然你确实需要发布新提交的sha1,否则你可以修改它(和证书)并使用新的sha1来声明新提交历史中的任何内容。一如既往,它创造了相互信任的网络。
答案 1 :(得分:1)
我不是因为我跟随,因为Linus确实让Git考虑到了这个特定的功能(即你输入的完整性是完全出来的是什么)
见2007 speech at Google(transcript):
我们中的大多数人都可以在没有尝试的情况下丢弃。
- 如果你没有分发,你就不值得使用,就这么简单。
- 如果你表现不好,就不值得使用,就这么简单。
- 如果你不能保证我放入SCM的东西完全相同,你就不值得使用了。
坦率地说,那里几乎照顾到了所有东西。
有很多SCM系统无法保证您从中获得的内容与您输入的内容相同。
如果您有内存损坏,如果您有光盘损坏,您可能永远不会知道 您知道的唯一方法是,当您检出文件时,您会注意到文件中存在损坏。源控制管理系统根本不能保护您 这甚至不常见。这是非常常见的。
所以我认为添加另一个完整性功能不会增加任何价值 而且“时间戳”也不是一个好主意,因为它们不是首先为DVCS录制的(参见“Git: checking out old file WITH original create/modified timestamps”和“What's the equivalent of use-commit-times for git?”)
答案 2 :(得分:0)
我刚刚编写了一个名为" GitLock "正是为了这个目的。它会为您的仓库添加可信的时间戳。
答案 3 :(得分:0)
我写了一篇文章,详细介绍了使用 RFC3161 时间戳为 git 存储库添加时间戳的详细信息,并提供了一个自动执行此操作的提交后挂钩:
关键点如下:
SHA1 可能不再被认为是安全的,特别是如果它要在几年后证明某些东西 (https://sha-mbles.github.io/)。因此,建议使用 sha256 哈希 void functions::diff(int error) {
error = error;
auto diff2 = [&error](void) {
error = 0;
cout << "Joe mama testing 123";
auto easy = [](void) {
cout << "Joe mama again";
};
easy();
};
diff2();
}
初始化 git 存储库(即使 sha256 支持仍被认为是实验性的)
将时间戳(和 LTV 数据)与存储库存储在一起有很多好处——尤其是为了任意延长时间戳令牌的生命周期以及保护它们不会因私钥泄露而失效,通过将先前时间戳的 CRL 数据添加到存储库,然后使用新时间戳对其进行时间戳。
Git 非常适合使用 RFC3161 进行时间戳记,这为其提供了所有数据更改的防篡改证据记录。