Worum es geht
Eine Hash-Kette in der eigenen Datenbank kann jeder neu berechnen, der die Datenbank beherrscht. Er ändert einen Eintrag und rechnet alle folgenden Hashes stimmig neu. Die Kette allein merkt das nicht.
Dagegen hilft ein Zeitstempel: eine signierte Bestätigung, dass ein bestimmter Hash zu einer bestimmten Zeit schon existierte. CRMS lässt in festen Abständen die letzten Einträge aller Journale stempeln. Das nennt man Verankern, das Ergebnis heißt Anker.
Wie die Journale aufgebaut sind, steht unter Die zwei Hash-Ketten.
Ein Ankerlauf
-
1CRMS→Datenbankliest den Kopf des System-Journals und den Kopf des Journals jedes Mandanten, jeden in seinem eigenen Kontext
-
2CRMSbaut aus allen Köpfen einen Merkle-Baum und berechnet seine Wurzel
-
3CRMSlässt die Wurzel von der Zeitstempel-Stelle stempeln (RFC 3161)
-
4CRMS→Datenbankspeichert den Anker in der System-Datenbank
-
5CRMS→Datenbanklegt zu jedem Journal seinen Beweispfad in die Datenbank dieses JournalsErgebnis: Jeder Mandant hält den Beweis für sein eigenes Journal
- Wie oft: alle
CODAMAI_CRMS_ANCHOR_INTERVAL(StandardPT1H, also stündlich). Der erste Lauf beginnt eine Minute nach dem Start. - Welche Mandanten: alle, die CIAS kennt, auch gesperrte und geschlossene. Auch ihr Journal muss verankert bleiben.
- Wenn ein Mandant nicht erreichbar ist: Er wird ausgelassen, die anderen werden verankert. Der nächste Lauf versucht es wieder.
- Wer läuft: jede Instanz mit
CODAMAI_CRMS_SCHEDULING_ENABLED=true(Standard). Bei mehreren Instanzen lässt du es in genau einer an.
Der Merkle-Baum
Ein Merkle-Baum fasst viele Hashes zu einem einzigen zusammen, der Wurzel. Immer zwei Hashes werden zusammen gehasht, bis nur einer übrig ist. Damit reicht ein Zeitstempel für alle Mandanten, egal wie viele es sind.
flowchart BT A["Blatt: system"] --> AB["Knoten"] B["Blatt: acme"] --> AB C["Blatt: beta"] --> CD["Knoten"] D["Blatt: gamma"] --> CD AB --> R["Wurzel → Zeitstempel"] CD --> R
- Ein Blatt ist das kanonische JSON
{journal, sequence, hash}des Journal-Kopfs. Die Blätter sind nach Journal sortiert, also ergeben dieselben Köpfe immer dieselbe Wurzel. - Der Baum folgt RFC 6962: Blätter bekommen vor dem Hashen das Byte
0x00, Knoten0x01. - Der Beweispfad eines Journals sind die Nachbar-Hashes auf dem Weg vom Blatt zur Wurzel. Mit ihm zeigt ein Mandant, dass sein Journal-Kopf in der gestempelten Wurzel steckt, ohne die Journale der anderen zu sehen.
Was die Ankerprüfung findet
Die Ankerprüfung nimmt den neuesten Beweispfad eines Journals und prüft ihn Station für Station. Zusammen mit der Prüfung der Kette selbst findet sie auch ein Journal, das stimmig neu berechnet wurde.
-
CRMSBeweisGibt es einen Beweispfad für dieses Journal?↳ nein
journal-not-anchored -
CRMSAnkerLiegt der genannte Anker in der System-Datenbank?↳ nein
anchor-missing -
CRMSEintragIst der Journal-Eintrag an der verankerten Stelle noch derselbe?↳ nein
anchor-entry-mismatch– umgeschrieben -
CRMSPfadFührt der Beweispfad zur Wurzel des Ankers?↳ nein
anchor-proof-invalid -
CRMSZeitstempelIst der Zeitstempel auf der Wurzel gültig?↳ nein
anchor-timestamp-invalid - Journal ist bis zum verankerten Eintrag belegt
Diese Ergebnisse sind Schlüssel in einem Prüfergebnis, keine Fehlerantworten.
Die Zeitstempel-Stelle
Eine Zeitstempel-Stelle (englisch Time Stamping Authority, TSA) signiert Hashes mit einer Zeitangabe. CRMS bringt eine eigene mit, die nach RFC 3161 arbeitet:
- Ihr Schlüssel kommt als PKCS#12-Datei, Base64-kodiert, aus
CODAMAI_CRMS_TSA_KEYSTORE, das Passwort ausCODAMAI_CRMS_TSA_KEYSTORE_PASSWORD. Ohne Schlüssel startet CRMS nicht. - Das Zertifikat muss die Verwendung
timeStampingtragen, und zwar als kritisch markiert. Sonst startet CRMS nicht. - Die Zeit kommt von der Systemuhr. Halte sie synchron, zum Beispiel per NTP.
- Jeder Zeitstempel hat eine zufällige 128-Bit-Seriennummer und trägt das Zertifikat, mit dem er signiert wurde.
Welchem Zeitstempel CRMS vertraut
Ein Zeitstempel wird gegen das Zertifikat geprüft, das ihn signiert hat. Dieses Zertifikat muss vertrauenswürdig sein, und es muss zum Zeitpunkt des Stempels gültig gewesen sein.
| Signiert mit dem aktuellen Zertifikat? | Zertifikat in der Vertrauensliste? | von einem Zertifikat der Liste ausgestellt? | Wird der Stempel anerkannt? |
|---|---|---|---|
| ja | – | – | ja |
| nein | ja | – | ja |
| nein | nein | ja | ja |
| nein | nein | nein | nein |
Die Vertrauensliste ist CODAMAI_CRMS_TSA_TRUSTED_CERTIFICATES: PEM-Zertifikate hintereinander, oder dieses PEM als Base64, wenn die Umgebung keine Zeilenumbrüche erlaubt. Die Zertifikate sind öffentlich, kommen aber immer aus der Konfiguration, nie aus der Datenbank. Sonst könnte die Datenbank-Administration ein eigenes Zertifikat hinzufügen und eine umgeschriebene Geschichte stempeln.
Ablauf des Zertifikats
Wann: mehr als 60 Tage bis zum Ablauf
CRMS startet und stempelt normal.
Ergebnis: Anker entstehen wie geplant
Wann: weniger als 60 Tage bis zum Ablauf
Der Start warnt im Log mit dem Ablaufdatum. Der Ankerlauf warnt zusätzlich, höchstens einmal am Tag.
Ergebnis: Anker entstehen weiter. Tausche jetzt den Schlüssel
Wann: das Zertifikat ist beim Start nicht gültig
Der Start scheitert und nennt die Gültigkeitsdaten des Zertifikats.
Ergebnis: CRMS läuft nicht
Wann: das Zertifikat läuft ab, während CRMS läuft
Jeder Ankerlauf wird mit timestamp-certificate-expired abgelehnt. Die Journale bleiben intakt, nur kommt kein neuer Anker dazu.
Ergebnis: Kein Anker, bis ein gültiger Schlüssel eingesetzt ist
Den Schlüssel tauschen
-
1Adminerzeugt einen neuen Zeitstempel-Schlüssel mit
timeStampingals kritischer Verwendung -
2Adminexportiert vorher das aktuelle Zertifikat als PEM
-
3Adminsetzt den neuen Schlüssel in
CODAMAI_CRMS_TSA_KEYSTOREund hängt das alte Zertifikat anCODAMAI_CRMS_TSA_TRUSTED_CERTIFICATESan -
4CRMSstempelt ab dem nächsten Lauf mit dem neuen Schlüssel. Nichts wird neu gestempeltErgebnis: Alte und neue Anker bleiben prüfbar
Mit einer eigenen Zertifizierungsstelle trägst du stattdessen deren Zertifikat in die Liste ein. Dann wird jedes Zeitstempel-Zertifikat anerkannt, das sie ausstellt, und ein Tausch braucht keine Änderung der Liste.
Die Variablen im Überblick stehen unter Konfiguration.