我如何使用RFC3161(可信)时间戳来证明我的Git存储库中的提交时间? [英] How can I use RFC3161 (trusted) timestamps to prove the age of commits in my Git repository?

查看:222
本文介绍了我如何使用RFC3161(可信)时间戳来证明我的Git存储库中的提交时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新



我有张贴了一个脚本我用这个到StackExchange代码评论网站。



我的原始问题是是否有一种方法可以使用X.509证书和时间戳签署Git提交?。有一段时间,我认为我只能用我的X.509证书签署了由可信赖的第三方时间标记的东西。不是这种情况。使用X.509证书进行数字签名和可信时间戳是互斥的。我已经更新了我的问题以反映这一点。



正如VonC指出的,签署Git提交的X.509证书不会增加任何价值。使用GPG密钥是一个更好的选择,因为Git的内置支持。



我接受了Greg的回答,因为它与我所要求的最接近,即使我原来的问题有点模糊。正如Greg指出的那样,如果您能证明您在某个时间点知道提交哈希值,那么可以确保您知道哈希当时的存储库内容,并且不需要在存储库中存储任何额外的数据。时间戳数据可以存储在任何地方。



可以使用 openssl (v1.0.0 +)和 curl 为请求散列提供RFC3161时间戳。



请求时间戳






  • URL - RFC3161时间戳服务

  • REV - 你想要一个timstamp的版本(散列)。必须是完整散列。 类型: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 。如果时间戳服务拒绝请求,它也可能输出错误。



    验证时间戳



    类似于请求时间戳,但您还需要:


    • CAFILE - 从时间戳服务返回到根CA的证书链



    时间戳服务应使用由受信任的权威机构颁发的证书对时间戳进行签名。如果没有,你的时间戳没有太大的可信度。如果找不到或创建适当的证书链,请尝试使用由 curl 发布的 cacert.pem 。这是此处



    下面的代码片段假定一个现有的,已签名的时间戳答复被传递给 stdin 。应该可以将上述请求直接输入到下面的验证命令中。如果您将请求的响应存储在一个变量中,则可能需要base64进行编码/解码( man base64 )。

    openssl ts -verify -digest$ REV-in / dev / stdin -CAfile$ CAFILE

    如果您查看回复,您会注意到请求摘要与所使用的Git修订相匹配。您可以使用此命令检查纯文本版本的回复。


    $ b

      openssl ts -reply  - in / dev / stdin -text 

    以下是我添加Git的回复示例修正在顶部。

      --------------------- -------------------------------------------------- --------- 
    版本:871d715e5c072b1fbfacecc986f678214fa0b585
    ------------------------------ --------------------------------------------------
    状态信息:
    状态:已授予。
    状态描述:未指定
    失败信息:未指定

    尖峰信息:
    版本:1
    策略OID:1.3.6.1.4.1.6449.2.1.1
    散列算法:sha1
    消息数据:
    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 ...
    序列号:0xB2EA9485C1AFF55C6FFEDC0491F257C8393DB5DC
    时间戳:8月15日08:41:48 2012 GMT
    准确度:未指定
    排序:no
    Nonce:0x615F0BF6FCBBFE23
    TSA:DirName:/ C = GB / ST =更大的曼彻斯特/ L = Salford / O = COMODO CA有限公司/ CN = COMODO时间戳签名者
    扩展名:



    其他注意事项



    冲压服务要求用户为脚本签名请求添加延迟。确保你知道你计划使用的服务是否需要它。在写这篇文章的时候,Comodo要求在脚本请求之间延迟15秒。我选择使用Comodo的唯一原因是因为那是我从我那里购买了我的代码签名证书的人。



    Git笔记似乎是存储已签名时间戳答复的明显选择,但我没有完整的解决方案发布。我被困在此时此刻。



    我的原始问题和更新如下。






    我希望能够在我的Git提交正在发生时证明,并且我的存储库的历史记录未被重写。它不一定是每一次提交。一天一次或一周一次就足够了。是否有推荐的方式来执行此操作?



    我知道我可以用GPG键签署Git提交,但我想知道是否有一种方法可以签署我的提交使用X.509证书并使用在线时间戳服务,如 http://timestamp.comodoca.com / rfc3161
    $ b

    如果不是,将使用 git rev-parse --verify HEAD

    Clarity



    我知道Git确保存储库的完整性,但据我了解,如果我控制存储库,第三方必须相信我没有重新编写仓库的历史记录,或者将我的时钟重新编译并创建了一个完全假的仓库,只是为了'证明'我的代码比实际的年代久远?我也不想公开发布我的存储库。



    这是一个虚构的用例,它应该让我更好地理解我想要做什么。 b
    $ b

    我在线发布了一些代码。一年后,某人在一本书或一篇文章中复制并发布相同的代码,并声称我是复制它们的人。此时,我希望能够拿到我的存储库,并证明我在一年前提交了该代码,然后再重新发布它。



    通过使用具有时间戳服务的X.509证书我可以在发生签名时证明。只要我能证明我知道一年前提交的散列,Git就可以保证存档的完整性。

    另外,有没有办法使用签名提交一个GPG密钥,但带有经过验证的时间戳?是否有可信的第三方提供与X.509证书类似的时间戳服务,但对于GPG?

    GPG密钥和X.509证书。假设我在存储库中保存了我的(公共)GPG密钥的副本,如果我在每天结束时做了以下工作,那么会进行以下工作吗?


    1. 使用我的X.509证书和在线时间戳服务签署我的(公共)GPG密钥。

    2. 使用我的(私人)GPG签名将更改提交到存储库
    3. 您只需发布SHA1(提交ID)公开。如果你愿意,你可以带上SHA1并用你的X.509证书签名(使用适当的时间戳服务),并保持这个状态。如果有人挑战你的作者身份,你可以很容易地表明你在产生特定SHA1的特定时间知道存储库的内容。您不需要实际在代码库中存储任何签名


      Updated

      I have posted a script I'm using for this to the StackExchange Code Review site.

      My original question for this was Is there a way I can sign a Git commit with an X.509 certificate and timestamp?. For a while I thought I could only get things I've signed with my X.509 certificate timestamped by a trusted third party. This is not the case. Digital signing with an X.509 certificate and trusted time stamping are mutually exclusive. I have updated my question to reflect this.

      As pointed out by VonC, signing Git commits with an X.509 certificate doesn't add any value. Using a GPG key is a much better option because of Git's built in support.

      I have accepted Greg's answer because it's the closest to what I was asking for, even though my original question was a bit ambiguous. As Greg points out, if you can prove you knew a commit hash at a certain point in time, that guarantees you knew the repository content the hash is for at that time and there's no need to store any extra data in the repository. The timestamp data can be stored anywhere.

      It's possible to use openssl (v1.0.0+) and curl to request RFC3161 timestamps for commit hashes.

      Request A Timestamp

      You'll need to have a bit of info for this:

      • URL - An RFC3161 time-stamping service
      • REV - The revision (hash) you want a timstamp for. Must be a full hash.

      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
      

      The above will output the signed timestamp to stdout. It may also output an error if the timestamp service refuses the request.

      Verify A Timestamp

      This is very similar to requesting a timestamp, but you also need:

      • CAFILE - A certificate chain from the timestamp service back to a root CA

      The time-stamping service should be signing timestamps with a certificate that was issued by a trusted authority. If not, your timestamps don't have much credibility. If you can't find or create a proper certificate chain, try using the cacert.pem published by curl. It's here.

      The below snippet assumes an existing, signed timestamp reply is being passed to stdin. It should be possible to pipe the above request directly into the below verify command. If you store the response from the request in a variable it may be necessary to base64 encode / decode it (man base64).

      openssl ts -verify -digest "$REV" -in /dev/stdin -CAfile "$CAFILE"
      

      If you examine a reply, you'll notice the request digest matches the Git revision that was used. You can examine a plain text version of a reply with this command.

      openssl ts -reply -in /dev/stdin -text
      

      Here is an example of a reply where I've added the Git revision at the top.

      --------------------------------------------------------------------------------
      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:
      

      Other Notes

      A lot of time-stamping services ask users to add a delay to scripted signing requests. Make sure you find out if the service you plan to use requires it. At the time of writing the one I'm using, Comodo, asks for a 15 second delay between scripted requests. The only reason I chose to use Comodo is because that's who I bought my code signing certificate from.

      Git notes seems like the obvious choice for storing signed timestamp replies, but I don't quite have a complete solution to post. I'm stuck on this at the moment.

      My original question and updates are below.


      I would like to be able to prove when my Git commits are happening and that the history of my repository hasn't been re-written. It doesn't have to be every commit. Once a day or once a week would be sufficient. Is there a recommended way to do so?

      I know I can sign Git commits with a GPG key, but I'm wondering if there's a way I can sign my commits with an X.509 certificate and the use of an online time-stamping service like http://timestamp.comodoca.com/rfc3161.

      If not, would dumping the current revision using git rev-parse --verify HEAD into a text file once a day, signing that file, and committing be sufficient to prove (roughly) when my code was written?

      Added Info For Clarity

      I know that Git guarantees the integrity of a repository, but, as far as I understand, if I control the repository a third party would have to trust that I haven't re-written the history of the repository or rolled my clock back and created a completely fake repository just to 'prove' my code is older than it actually is? I also don't want to publish my repository publicly.

      Here's a fictional use cases that should give a better idea of what I want to do.

      I publish some code online. A year later someone copies and publishes the same code in a book or article and claims I was the one that copied them. At that point, I would like to be able to take my repository and prove that I committed that code a year ago, before they re-published it.

      By using an X.509 certificate with a time-stamping service I can prove when the signing occurred. As long as I can prove I knew the hash for the year old commit, Git guarantees the integrity of the archive.

      Alternatively, is there a way to sign a commit using a GPG key, but with a verified time-stamp? Is there a trusted third party that provides a time-stamping service similar to the ones available for X.509 certificates, but for GPG?

      Maybe I could use a combination of a GPG key and an X.509 certificate. Assuming I keep a copy of my (public) GPG key in the repository, would the following work if I did it at the end of each day?

      1. Sign my (public) GPG key using my X.509 certificate and an online time-stamping service.
      2. Commit the change to the repository with a signature from my (private) GPG key.

      解决方案

      All you have to do, is publish the SHA1 (the commit id) publicly. If you like, you can take that SHA1 and sign it with your X.509 certificate (using an appropriate timestamping service) and keep that around. If anybody challenges your authorship, you can easily show that you knew the contents of the repository at the particular time that generated that particular SHA1. You don't need to actually store any signature inside the code repository.

      这篇关于我如何使用RFC3161(可信)时间戳来证明我的Git存储库中的提交时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆