Proof of existence
„Proof of Existence“ hilft, später nachzuweisen, dass man zu einem bestimmten Zeitpunkt eine bestimmte Datei oder einen bestimmten Datenbestand vorliegen hatte.
Zum Beispiel kann man damit beweisen, wann man eine bestimmte Idee hatte; der „Datenbestand“ ist in dem Fall einfach eine Text- oder Officedatei, in die hinein man die Idee aufgeschrieben hat (und hoffentlich sich selbst als Autor genannt).
Die Datei selbst verwahrt man gut geschützt auf. Als ihr Stellvertreter wird ihr „Fingerabdruck“ genutzt, also ein kryptographisch sicherer Hashwert, zum Beispiel der SHA256.
Um später beweisen zu können, wann man die Idee hatte, möchte man diesen SHA256-Fingerabdruck möglichst unfälschbar mit einem Zeitstempel verknüpfen, zu dem er vorlag.
Die HTTPS-Idee
Eine gängige Möglichkeit, das zu tun, ist es, den Hash in die Blockchain einer Kryptowährung einzubetten. Die Luxembourger Börse nutzt ein entsprechendes Verfahren. Ein entsprechender Dienst ist öffentlich verfügbar.
Eine andere einfache Möglichkeit, das zu tun, ist es, den SHA256-Wert in einen Hostnamen einzubetten und sich ein gängiges HTTPS-Zertifikat für diesen Hostnamen zu besorgen. Im Zertifikat wird der Hostname von einer (hoffentlich) vertrauenswürdigen Stelle digital unterschrieben. Diese digitale Unterschrift ist mit einem Zeitstempel versehen: Dem Beginn der Gültigkeit des Zertifikats.
Durch bloßes Vorweisen des Zertifikats kann man beweisen, zu diesem Zeitstempel über ein Dokument mit dem fraglichen Hash verfügt zu haben.
Beispielhafte Umsetzung
Dieses Konzept wurde probehalber in die Praxis umgesetzt wie folgt:
Eine Zusammenfassung (Vorabversion) dieser Idee wurde zunächst in
einer eigenen Datei idea.txt
abgelegt. Wichtig
ist, dass der Autor mit dabei steht. Um zu schauen, wie lange die
Umsetzung dauert, habe ich auch einen Zeitstempel mit hinein
geschrieben.
Die sha256sum Prüfsumme dieser Datei ist, hexadezimal ausgedrückt:
b42edb7736acfe1f990596d8de2f9f66a8b286785f6ccbf845bc90b378bbf30d
Leider erlaubt DNS nur Namen von maximal 63 Zeichen Länge. Dieser Hexstring ist aber 64 Zeichen lang. Als Behelf wird er durch einen „.“ in zwei DNS-Namen zerlegt (Host und Subdomain).
Ich habe auf die Schnelle meine private Domain famsik.de
für dieses
Experiment herangezogen. Das war bequem, denn für diese Domain habe
ich die nötigen Skripte für lets' encrypt schon installiert und volle
Kontrolle über DNS und Webserver. Man hätte die Umsetzung auch über
eine beliebige andere eigene Domain machen können, die in einer Cloud
gehostet ist.
Ich habe also zunächst im DNS einen Eintrag angelegt
b42edb7736acfe1f990596d8de2f9f66.a8b286785f6ccbf845bc90b378bbf30d.famsik.de
und gewartet, bis er global zur Verfügung steht. Zwischendurch habe ich den Webserver passend konfiguriert und dann das HTTPS-Zertifikat besorgt und eingespielt.
Überprüfung
Nun kann jeder meine Behauptung überprüfen, dass ich mir diese Idee am oder vor dem 13.2.2018 ausgedacht habe. Das geht so:
Man besorgt sich die Datei idea.txt
, und überprüft
erstens, dass sie inhaltlich diese Idee beschreibt und zweitens die
Prüfsumme:
$ sha256sum idea.txt b42edb7736acfe1f990596d8de2f9f66a8b286785f6ccbf845bc90b378bbf30d idea.txt
Nun besorgt man sich den Schlüssel, den mein Webserver ausliefert. Solange der noch nicht abgelaufen ist, kann man das tun mit
name=b42edb7736acfe1f990596d8de2f9f66.a8b286785f6ccbf845bc90b378bbf30d.famsik.de openssl s_client -connect $name:443 -servername $name -verify_return_error -showcerts < /dev/null
Später gibt es den Schlüssel hier: key1.pem.
Nun überprüft man, dass im Output von
openssl x509 -in key1.pem -noout -text
erstens ein passender Zeitstempel auftaucht
Validity Not Before: Feb 13 14:06:01 2018 GMT
und zweitens der gesuchte Hash-Wert:
X509v3 Subject Alternative Name: DNS:b42edb7736acfe1f990596d8de2f9f66.a8b286785f6ccbf845bc90b378bbf30d.famsik.de, ...
Schließlich ist (wie üblich) zu überprüfen, ob der Schlüssel valide ist. Dazu benötigt man den Zwischenschlüssel key2.pem und kann sich zum Beispiel des folgenden Befehls bedienen:
$ openssl verify -untrusted key2.pem key1.pem key1.pem: OK
Probleme dieses Ansatzes
Zeitstempel-Genauigkeit
Ich habe das Zertifikat laut Log um 15:05:47 UTC bei lets' encrypt angefordert, das entspricht 16:05:47 MEZ. Das ausgestellte Zertifikat gilt aber bereits knapp eine Stunde eher. Offensichtlich umgeht lets' encrypt so Probleme mit ungenau gehenden Uhren. Für „Proof of Existence“-Zwecke wären präzise Zeitstempel nützlicher.
Ob die Zeitstempel-Ungenauigkeit vorhanden ist und stört, kommt auf den verwendeten Zertifikats-Ausstellerdienst an und den Anwendungsfall.
Abgelaufende Zertifikate
Der „Proof of Existence“ gelingt, so lange das Zertifikat gültig ist.
Nach Ablauf seiner Gültigkeit lässt sich noch überprüfen, ob es zu einem
relevanten früheren Zeitpunkt gültig war. Zum Beispiel kann man
openssl
fragen: „War dieses Zertifikat am 2018–02–13 16:00 MEZ
gültig?“
Dazu vergewissert man sich, dass „2018–02–13 16:00 MEZ“ einem UNIX-Zeitstempel von 1518534000 entspricht, und führt aus:
openssl verify -attime 1518534000 -untrusted key2.pem key1.pem
Das Hantieren mit bereits abgelaufenen Zertifikaten ist natürlich eine zunächst etwas anrüchige Angelegenheit.
Man kann dieses Problem dadurch angehen, dass man eine Kette baut: Kurz vor Ablauf der Gültigkeit des Zertifikats erstellt man ein neues Dokument. Dieses Dokument enthält Hash-Werte des ursprünglichen, zu schützenden Dokuments sowie den Hash-Wert des (zu diesem Zeitpunkt noch gültigen) Zertifikats (Hash-Werte beider Keys o.ä.). Für dieses Dokument erstellt man nun einen neuen „Proof of Existence“, wofür ein neues Zertifikat besorgt wird. Das Ziel dieser Übung: Dieses neue Zertifikat gilt nun weiter in die Zukunft hinein als das alte. Ehe es abläuft, schmiedet man analog wieder ein neues Glied an die Kette.
Selbst, wenn man an eine Zertifizierungsstelle gerät, die nach Ablauf der Zertifikate die zu ihrer Ausstellung benutzten privaten Schlüssel veröffentlicht, kann man mit Hilfe dieser Kette doch nachweisen, dass man die Zertifikate schon hatte, ehe die jeweiligen Schlüssel veröffentlicht wurden.