Externer Anker: Audit-Kette HMAC-signiert (Hash-Version 3)

Schliesst den nach R166/R167 verbliebenen Grenzfall: Bis Version 2 war die
Kette selbsttragend - wer die DB schreiben kann, konnte jede Zeile aendern und
alle Folgehashes konsistent nachziehen, die Pruefung meldete "gueltig".

Version 3 signiert denselben Inhalt per HMAC-SHA256 mit AUDIT_HMAC_KEY, einem
Schluessel ausserhalb der Datenbank. Ohne ihn laesst sich keine gueltige
Signatur erzeugen; reiner DB-Schreibzugriff genuegt nicht mehr.

Fail-safe: Ohne Schluessel wird weiter Version 2 geschrieben, es faellt nichts
aus. Signierte Zeilen gelten dann als nicht pruefbar (unverifiableEntries) und
ausdruecklich nicht als manipuliert. AUDIT_HMAC_KEY_OLD erlaubt einen
Schluesselwechsel ohne Rehash.

Restluecke der Versionsgrenze geschlossen: Wird die FRUEHESTE Zeile einer Stufe
herabgestuft, wandert MIN(id) mit - die Grenze allein haette den Downgrade
durchgewunken (der erste Testlauf fiel genau darauf durch). Der Nachfolger ist
jedoch HMAC-signiert und sein previousHash ohne Schluessel nicht faelschbar;
eine unerklaerte Luecke vor einer signierten Zeile gilt deshalb als Befund.

Verifiziert: Inhalt geaendert -> erkannt; Downgrade 3->2 auf der fruehesten
V3-Zeile -> erkannt; dasselbe auf der letzten V3-Zeile (kein Nachfolger) ->
erkannt; ohne Schluessel 0 manipuliert / 2 nicht pruefbar; 40 parallele
Schreiber -> 40/40, 0 Forks, alle V3. tsc + vite build gruen.

AUDIT_HMAC_KEY in .env.example dokumentiert. Der Schluessel selbst liegt nur
lokal in .env (gitignored).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 18:50:57 +02:00
co-authored by Claude Opus 5
parent 1a349d142e
commit 044a12f73e
5 changed files with 173 additions and 27 deletions
+18
View File
@@ -19,3 +19,21 @@ ENCRYPTION_KEY="32-byte-hex-key-for-aes-256-gcm"
# Server
PORT=3001
NODE_ENV=development
# ==================== AUDIT-ANKER ====================
# Signiert Audit-Log-Eintraege per HMAC-SHA256 mit einem Schluessel, der NICHT
# in der Datenbank liegt. Damit reicht ein reiner DB-Schreibzugriff nicht mehr
# aus, um die Hash-Kette glaubwuerdig umzuschreiben (Pentest R166/R167).
#
# Erzeugen: openssl rand -hex 32
# Fail-safe: Ohne Schluessel schreibt das Audit-Log weiter die unsignierte
# Version 2 - es faellt nichts aus, der Anker fehlt nur.
# ACHTUNG: Schluessel sichern. Geht er verloren, sind alle damit signierten
# Eintraege nicht mehr pruefbar (sie gelten dann als "nicht pruefbar",
# NICHT als manipuliert).
AUDIT_HMAC_KEY=
# Nur waehrend eines Schluesselwechsels setzen: der vorherige Schluessel wird
# bei der Pruefung zusaetzlich akzeptiert, damit Altbestand ohne Rehash gueltig
# bleibt. Nach dem Wechsel wieder leeren.
AUDIT_HMAC_KEY_OLD=