如何证明一份文档没有被事后改写
一个项目发布了白皮书。六个月后,网站上的数字变了,而网站上的白皮书与网站一致。白皮书被改过吗?通常无从判断——而让它变得可判断其实很容易。
为什么显而易见的答案不管用
- 文档里的日期。写文档的人打上去的,改文档的人可以改。
- 文件的修改时间。那是你这份副本的属性,不是文档的属性。复制一下就重置了。
- 页面上的发布日期。发布方控制的数据库里的一个字段。
- 互联网档案馆。确实有用,而且不在发布方控制之下——但它只抓到它碰巧访问时碰巧看到的东西。没有抓取,就没有证据。
这些本身都不算不诚实,它们只是不构成证据,因为本该被它们约束的那一方,正是控制它们的那一方。
什么才真正管用
两样东西,而且都不需要信任发布方。
校验和——一个 SHA-256 哈希——是由文件的字节算出的一串短字符。任何位置改动一个字符,这串字符就会完全不同。它不可逆,也无法伪造:你造不出一份内容不同而哈希相同的文档。所以,一个公布的哈希锁定了唯一一份确切的文件。
时间戳证明把这个哈希提交进比特币区块链,从而把它系在某个时刻上。要改写这条记录,就得改写比特币。它证明的东西很窄,也很有用:这份确切的文件不晚于这个区块就已存在。
两者合起来完整地回答了那个问题。哈希说明是哪一份文件。证明说明它何时存在。两者都不经过发布方,任何有终端的人都能核查。
两条命令核查一份文档
下载文档和它的证明文件——通常是放在旁边、以 .ots 结尾的一个小文件。然后计算哈希,并与公布的值比对:
sha256sum document.docx
如果吻合,你手上就是当初公布的那份确切文件。接下来用 OpenTimestamps 客户端验证它何时存在:
ots verify document.docx.ots
客户端会报出比特币区块及其日期。这就是证明,而且它完全不联系项目方——只查区块链。
一个常让人栽跟头的实际提醒:用文字处理软件打开文档再保存,哪怕一个字没改,也会重写字节。校验和随之对不上,证明也不再匹配。先验证再编辑,并保留原件。
它证明什么,不证明什么
- 证明:这份文件以这个确切形态在那个日期或更早已经存在。
- 不证明:是谁写的。任何人都可以为任何人的文档打时间戳。
- 不证明:其内容为真。一份带时间戳的预测,仍然只是一份带日期的预测。
- 不证明:它是唯一的版本。项目可以给多份草稿打时间戳,然后只拿出好看的那份给你——所以已公布证明的整个集合,和任何单一证明同样重要。
为什么这么少的项目这么做
它不花钱。日历服务器是免费的,客户端装一个包就有,打一次时间戳只需一秒。它之所以罕见,原因不是成本——而是它取消了一个选项。文档一旦被打上时间戳,悄悄修订就不再可行,里面的数字就必须被辩护,而不能被调整。
这让它的缺席也变得有信息量。发布文档却不带校验和的项目,未必藏着什么。而公布校验和的项目是在告诉你:它接受了一个约束,而且你可以验证这个约束是否成立。
Common questions
我需要运行比特币节点吗?
不需要。客户端会用公开的区块数据核查证明。自己运行节点可以连这一点依赖也去掉,但核查有意义并不以此为前提。
如果证明显示“待确认”怎么办?
时间戳已经打上,但还没被锚定进区块——通常一小时左右。待确认的证明不是失败的证明,只是在升级之前它仍然依赖日历服务器。
项目能伪造时间戳吗?
时间戳伪造不了。它可以给一份文档打时间戳、却公布另一份,所以你要计算自己实际下载的那份文件的哈希再比对——正是这一步堵住了缺口。
本项目如何使用它
本站发布的每一份文档都带有 SHA-256 校验和以及锚定在比特币上的 OpenTimestamps 证明。新版本出现时旧版本从不删除,因此整个序列都保持可核查,而不只是当前那一份。校验和从不写在文档内部——一份文档无法包含自己的哈希——它放在文档页上,紧挨着文件。
上面那两条命令正是我们自己用的。请拿它们来核查我们的文档;如果有任何一项验证不通过,值得告诉我们。