Kann die Prüfung verschlüsselter Audit-Logs Löschungen erkennen?
Die Prüfung verschlüsselter Audit-Logs erkennt veränderte oder fehlende Datensätze in der Mitte. Für eine Kürzung am Ende braucht sie jedoch einen externen Checkpoint, der die Vollständigkeit belegt.

Eine Hash-Kette kann einen fehlenden Datensatz in der Mitte einer Auditdatei erkennen. Sie kann jedoch nicht zuverlässig feststellen, dass jemand Datensätze am Ende abgeschnitten hat. Genau diese Unterscheidung führt dazu, dass Teams die Aussagekraft ihres Prüfers überschätzen und bei einem Vorfall feststellen, dass sie zwar Integritätsbelege, aber keine vollständige Historie bewahrt haben.
Verschlüsselung ändert daran nichts. Sie schützt den Inhalt der Datensätze. Eine Kette über verschlüsselten Bytes kann zeigen, dass diese Bytes weiterhin wie erwartet miteinander verbunden sind, auch wenn niemand, der den Prüfer ausführt, sie entschlüsseln kann. Sie kann nicht beweisen, dass die Datei jeden jemals vorhandenen Datensatz enthält, solange kein Beleg außerhalb der Datei einen späteren Punkt ihrer Geschichte festhält.
NIST beschreibt eine Hash-Kette als append-only-Struktur, in der jeder Block einen Hash der vorherigen Daten enthält. Wird ein Block verändert, ändert sich dadurch der beim Nachfolger gespeicherte Digest. Das liefert einen Manipulationsnachweis, aber keine Zeitmaschine.
Die Kettenprüfung kontrolliert eine Beziehung, nicht die Vollständigkeit
Ein Prüfer kontrolliert, ob jeder Datensatz auf den richtigen Vorgänger verweist und ob sein Digest zu den gespeicherten Bytes passt. Ausgehend von einem vertrauenswürdigen ersten Datensatz kann er die lückenlose Verbindung durch alle noch vorhandenen Datensätze feststellen.
Angenommen, eine Datei enthält die Datensätze 1 bis 100. Datensatz 58 enthält den Digest von Datensatz 57, und Datensatz 59 enthält den Digest von Datensatz 58. Löscht jemand Datensatz 58 und lässt alles andere unverändert, verweist Datensatz 59 weiterhin auf einen Digest, den der Prüfer nicht findet. Die Prüfung schlägt an der Lücke fehl.
Entfernt man dagegen die Datensätze 91 bis 100, verweist Datensatz 90 weiterhin korrekt auf Datensatz 89. Nichts in der verkürzten Datei sagt, dass auf Datensatz 90 einmal zehn weitere Datensätze folgten. Ein Prüfer, der bei Datensatz 1 beginnt und am Dateiende stoppt, kann Erfolg melden. Er hat die ihm vorgelegte Historie geprüft. Er hat nicht geprüft, ob diese Historie vollständig ist.
Oft werden drei getrennte Aussagen zu «Das Log ist manipulationssicher» zusammengezogen:
- Die verbliebenen Datensätze wurden nicht verändert.
- Kein Datensatz wurde aus der Mitte entfernt.
- Die Datei endet dort, wo die ursprüngliche Historie endete.
Für diese Aussagen braucht man unterschiedliche Belege. Eine lineare Kette deckt die erste gut ab und erkennt eine einfache Variante der zweiten. Die dritte braucht eine unabhängige spätere Festlegung, die oft Checkpoint, Kopf, Siegel, Quittung oder Zeuge genannt wird.
Certificate Transparency trennt dieselben Aussagen mit einer anderen Datenstruktur. RFC 9162 zufolge kann ein Merkle-Konsistenznachweis zeigen, dass ein neuerer Baum gegenüber einem früher angekündigten Baum nur erweitert wurde. Der frühere angekündigte Baumkopf leistet dabei die entscheidende Arbeit. Ohne ihn sagt eine aktuelle Wurzel nichts über Datensätze aus, die ein Log-Betreiber nicht vorlegen wollte.
Erstelle ein Test-Log, das Nutzdaten als undurchsichtigen Ciphertext behandelt
Übe nicht mit einer produktiven Auditdatei. Erstelle ein wegwerfbares Testobjekt, dessen Nutzdaten für den Prüfer wie Ciphertext aussehen, und teste Löschungen anhand exakter Byte-Datensätze.
Das folgende Skript schreibt eine JSON-Lines-Datei. Jeder Datensatz enthält eine Sequenznummer, eine undurchsichtige Base64-Nutzlast, den Digest des Vorgängers und den eigenen Digest. Die Nutzlast besteht absichtlich aus zufälligen Testdaten und ist keine echte Verschlüsselung. Für diesen Test reicht das aus, weil der Kettenprüfer nur stabile undurchsichtige Bytes benötigt. In einem echten verschlüsselten Log ersetzt du sie durch den tatsächlich serialisierten Ciphertext-Datensatz samt authentifizierten Metadaten.
# make_log.py
import base64
import hashlib
import json
import os
OUT = "audit.jsonl"
ZERO = "0" * 64
def canonical(record):
return json.dumps(record, sort_keys=True, separators=(",", ":")).encode()
def digest(record):
return hashlib.sha256(canonical(record)).hexdigest()
prev = ZERO
with open(OUT, "w", encoding="utf-8") as f:
for seq in range(1, 13):
body = {
"seq": seq,
"ciphertext": base64.b64encode(os.urandom(24)).decode(),
"prev": prev,
}
body["hash"] = digest(body)
f.write(json.dumps(body, sort_keys=True) + "\n")
prev = body["hash"]
print(f"wrote 12 records to {OUT}")
print(f"head seq=12 hash={prev}")
Verwende einen separaten Prüfer, statt den Writer seine eigene Ausgabe kontrollieren zu lassen. Er sollte doppelte Sequenznummern, unerwartete Sprünge, fehlerhafte Datensätze, falsche Vorgängerverweise und falsche Hashes zurückweisen. Ein Prüfer, der nur Hashes kontrolliert, hat einen blinden Fleck: Er kann eine umsortierte Datei akzeptieren, wenn der Angreifer genügend zugehörige Felder ebenfalls neu angeordnet hat.
# verify_log.py
import hashlib
import json
import sys
ZERO = "0" * 64
def canonical(record):
return json.dumps(record, sort_keys=True, separators=(",", ":")).encode()
def digest_without_hash(record):
copy = dict(record)
supplied = copy.pop("hash", None)
return supplied, hashlib.sha256(canonical(copy)).hexdigest()
def fail(message):
print(f"FAIL {message}")
raise SystemExit(1)
path = sys.argv[1]
prev = ZERO
expected_seq = 1
last_hash = ZERO
with open(path, encoding="utf-8") as f:
for line_no, line in enumerate(f, start=1):
try:
record = json.loads(line)
except json.JSONDecodeError:
fail(f"line={line_no} invalid JSON")
if record.get("seq") != expected_seq:
fail(f"line={line_no} expected_seq={expected_seq} got={record.get('seq')}")
if record.get("prev") != prev:
fail(f"line={line_no} seq={expected_seq} predecessor mismatch")
supplied, calculated = digest_without_hash(record)
if supplied != calculated:
fail(f"line={line_no} seq={expected_seq} digest mismatch")
prev = supplied
last_hash = supplied
expected_seq += 1
print(f"OK records={expected_seq - 1} head={last_hash}")
Führe das Testobjekt aus und bewahre den gemeldeten Kopf außerhalb der Logdatei auf:
python3 make_log.py
python3 verify_log.py audit.jsonl
Das erfolgreiche Ergebnis sollte ungefähr so aussehen, bei jedem Lauf mit einem anderen Digest:
wrote 12 records to audit.jsonl
head seq=12 hash=8f...c2
OK records=12 head=8f...c2
Das Paar aus records=12 und head=... ist dein Checkpoint. Schreibe es in eine separate Testnotizdatei, bevor du Kopien veränderst. Wenn der Checkpoint nur in der Datei steht, die du angreifen willst, hast du lediglich eine praktische Aufzeichnung dessen erstellt, was der Angreifer ändern kann.
Das Entfernen des Endes zeigt die Grenze sofort
Das Löschen am Ende ist der Test, der beim Wort «vollständig» zur Vorsicht mahnen sollte. Kopiere die Datei, entferne die letzten drei Zeilen und führe denselben Prüfer aus.
cp audit.jsonl tail-cut.jsonl
head -n 9 audit.jsonl > tail-cut.jsonl
python3 verify_log.py tail-cut.jsonl
Der Prüfer wird für neun Datensätze Erfolg melden. Das soll er auch. Die Datensätze 1 bis 9 bilden weiterhin eine gültige Kette. Das als Prüferfehler zu bezeichnen, würde zu einem gefährlichen Design führen, in dem gültige Teilausschnitte wie beschädigte Dateien aussehen.
Vergleiche das Ergebnis stattdessen mit dem Checkpoint:
OK records=9 head=4a...91
expected records=12 head=8f...c2
Jetzt hast du einen Beleg für die Kürzung. Der Nachweis entsteht durch die Abweichung von einem Beleg, der aufgezeichnet wurde, als das Log länger war, nicht durch die internen Verknüpfungen der verkürzten Datei.
Eine Sequenznummer hilft bei der Diagnose. Sicherheit erzeugt sie allein nicht. Ein Angreifer, der das Ende umschreiben kann, kann die letzte Sequenznummer von 12 auf 9 ändern. Nützlich wird sie, wenn der erwartete Wert aus einer Quelle stammt, die der Angreifer nicht umschreiben kann, etwa aus einem signierten Checkpoint eines separaten Dienstes, einem geschützten Release-Artefakt oder einem Export, der eine andere administrative Domäne erreicht hat.
Diesen Test überspringen viele Audit-Designs, weil er zu offensichtlich wirkt. Nach einer zerstörerischen Aktion ist es jedoch genau dieser Fehler, der zählt. Ein bösartiger Prozess muss die Historie nicht intern widersprüchlich machen. Es reicht, sie früh genug enden zu lassen, um die Aktion zu verbergen.
Eine Löschung in der Mitte sollte fehlschlagen, aber nur unter klaren Bedingungen
Erstelle eine weitere Kopie und lösche einen Datensatz, der sowohl einen Vorgänger als auch einen Nachfolger hat. Datensatz 6 eignet sich gut.
cp audit.jsonl middle-cut.jsonl
sed '6d' audit.jsonl > middle-cut.jsonl
python3 verify_log.py middle-cut.jsonl
Das Ergebnis sollte ungefähr so aussehen:
FAIL line=6 expected_seq=6 got=7
Entfernst du die Sequenzprüfung, würde der Prüfer erst einen Test später fehlschlagen: Datensatz 7 enthält den Digest von Datensatz 6, während der Prüfer den Digest von Datensatz 5 erwartet. Behalte beide Prüfungen. Die abweichende Sequenznummer macht das Problem für den Bediener sichtbar, der Vorgängervergleich zeigt die gebrochene kryptografische Beziehung.
Behaupte nicht, dass eine Hash-Kette eine Löschung in der Mitte immer erkennt. Sie erkennt eine einfache Löschung, wenn der Angreifer die verbleibende Kette nicht umschreiben kann. Jeder kann mit einem öffentlichen Digest-Algorithmus neue Hashes berechnen. Kann jemand Datensatz 6 löschen, den Vorgängerverweis in Datensatz 7 ändern, dessen Hash neu berechnen und diese Arbeit bis zu Datensatz 12 fortsetzen, kann die neu aufgebaute Datei mit ihrem eigenen neuen Kopf erfolgreich geprüft werden.
Das ist weder ein Kollisionsangriff noch ein Bruch von SHA-256. Es ist eine gewöhnliche Neuberechnung. Das System hat eine neue Historie akzeptiert, weil kein geschützter Beleg vorhanden war, dass die alte Historie existierte.
Die Hinweise von NIST zu digitalen Beweismitteln formulieren den betrieblichen Punkt klar: Ein gespeicherter Hash muss an einem Ort liegen, an dem Personen mit Zugriff auf die Beweisdaten ihn nicht ändern oder überschreiben können. Im selben Bericht nennt NIST Hash-Ketten als nützlich zur Absicherung von Hashes, doch die externe Speicherung des Referenzwerts bleibt erforderlich.
Ein Test für die Löschung in der Mitte hat daher zwei Varianten:
- Eine Zeile löschen und die späteren Bytes unverändert lassen. Die Kette muss fehlschlagen.
- Eine Zeile löschen und jeden späteren Digest neu erzeugen. Die neu aufgebaute Kette muss beim Vergleich mit einem unabhängig aufbewahrten Checkpoint fehlschlagen.
Führt dein Testplan nur die erste Variante aus, prüft er Dateibeschädigung und nachlässige Manipulation. Er prüft keinen Angreifer, der in den Log-Speicher schreiben kann.
Verschlüsselung und Kettenintegrität beantworten unterschiedliche Fragen
Verschlüsselte Datensätze ermöglichen eine sinnvolle Aufgabenteilung. Betreiber können die Kette über Ciphertext prüfen, ohne Geheimnisse, Request-Bodies, Kommandoausgaben oder andere vertrauliche Auditdaten zu lesen. Ermittler mit entsprechender Berechtigung können relevante Datensätze später entschlüsseln. Für sensible Auditdaten ist das ein vernünftiges Design.
Verschlüsselte Bytes bestätigen jedoch nicht ihre eigene Herkunft. Ein Ciphertext-Datensatz kann gelöscht werden. Jemand, der den Verschlüsselungs- und Protokollierungspfad kontrolliert, kann einen neuen Ciphertext-Datensatz hinzufügen. Authentifiziert der Verschlüsselungsmodus die Daten nicht, kann ein Ciphertext unter Umständen so verändert werden, dass er zu unbrauchbaren Daten wird, ohne dass der Entschlüsseler den Grund erkennt. Verwende authentifizierte Verschlüsselung für Vertraulichkeit und Integrität der Datensätze und die Kette, um sie zu einer geordneten Historie zu verbinden.
Halte diese Prüfungen beim Design und im Vorfallsbericht getrennt:
- Die Datensatz-Authentifizierung fragt, ob ein verschlüsselter Datensatz verändert wurde.
- Die Kettenprüfung fragt, ob jeder verbliebene Datensatz auf den behaupteten Vorgänger folgt.
- Der Checkpoint-Vergleich fragt, ob die beobachtete Historie einen zuvor beobachteten Kopf erreicht.
- Die Ereigniserfassung fragt, ob das System die Aktion überhaupt ins Log geschrieben hat.
Die letzte Frage ist unangenehm. Kein kryptografisches Log kann beweisen, dass ein Ereignis aufgezeichnet wurde, wenn ein kompromittierter Writer sich entschieden hat, keinen Datensatz auszugeben. Du kannst dieses Risiko durch Belege von unabhängigen Grenzen verringern, etwa einem Netzwerkdienst, einer Host-Auditfunktion oder einem menschlichen Freigabeereignis. Durch die Bezeichnung des lokalen Logs als append-only verschwindet die Lücke nicht.
Sallyports Auditmodell ist in diesem Zusammenhang nützlich, weil die Journale für Agent-Läufe und einzelne Aufrufe aus einem verschlüsselten, Hash-verknüpften Audit-Log stammen und sp audit verify die Ciphertext-Kette offline ohne Vault-Schlüssel prüfen kann. So kann ein Prüfer die Kontinuität kontrollieren, ohne die Zugangsdaten oder Aktionsdaten offenzulegen, die der Audit-Trail schützt.
Ein Checkpoint muss schwer umzuschreiben sein, nicht nur kopiert werden
Ein Checkpoint ist eine Aussage über ein Log zu einem bestimmten Zeitpunkt. Er sollte mindestens eine Log-ID, die letzte Sequenznummer, den letzten Digest, die Erstellungszeit und die Format- oder Algorithmusversion enthalten. Behandle ihn als separates Artefakt mit eigener Verwahrung.
Dieses kleine Format reicht für ein Testgerüst:
{
"log_id": "agent-actions-test-a",
"sequence": 12,
"head": "8f...c2",
"created_at": "2026-07-22T14:30:00Z",
"format": "jsonl-chain-v1"
}
Vertraue dem Feld created_at nicht allein. Eine lokale Uhr ist zum Sortieren und Ermitteln hilfreich, aber ein Angreifer mit Kontrolle über den Rechner kann möglicherweise die Uhr und die Datei mit diesem Feld kontrollieren. Seine Aussagekraft erhält der Checkpoint dadurch, wohin er gelangt ist und wer ihn ändern kann.
Eine praktische Anordnung sieht vor, dass eine Partei die Auditdatensätze schreibt und eine andere Partei die Köpfe regelmäßig aufbewahrt. Diese zweite Partei braucht keinen Entschlüsselungszugriff. Sie muss nur genug Informationen haben, um eine spätere Datei abzulehnen, deren finaler Digest und deren Sequenz nicht zu den früher beobachteten Werten passen.
Bei einem Entwicklertool kann die unabhängige Stelle einfach sein: ein geschütztes CI-Artefakt, ein System für Release-Attestierungen, ein separates Collector-Konto oder ein täglicher Export, der von einem anderen Administrator freigegeben wird. Für riskantere Aktionen sollte der Checkpoint unmittelbar nach der Aktion erzeugt und außerhalb der Workstation aufbewahrt werden. Die Frequenz sollte zum akzeptierten Schadensfenster passen. Ein täglicher Checkpoint kann die Vollständigkeit der Stunden zwischen dem gestrigen Kopf und dem heute fehlenden Ende nicht belegen.
Das Signieren eines Checkpoints hilft, wenn Prüfer wissen müssen, wer ihn ausgestellt hat. Eine Signatur bindet die Checkpoint-Daten an die signierende Stelle, macht diese aber nicht ehrlich. Schreibt und signiert derselbe kompromittierte Prozess das Audit-Log und Ersatz-Checkpoints, besteht weiterhin nur eine Vertrauensgrenze. Platziere den Zeugen dort, wo der ursprüngliche Writer ihn nicht unbemerkt steuern kann.
Schreibblinder Speicher verändert den getesteten Angreifer
Eine Kette an einem Ort, an dem der Writer alte Datensätze frei bearbeiten kann, hat ein anderes Bedrohungsmodell als eine Kette über einen schreibblinden Append-Pfad. Beim ersten Design braucht man externe Zeugen, um Umschreibungen der Historie zu erkennen. Das zweite versucht, solche Umschreibungen von vornherein zu verhindern.
Sei beim Begriff «schreibblind» genau. Er sollte bedeuten, dass die Komponente, die einen neuen Datensatz einreicht, frühere verschlüsselte Logdatensätze nicht beliebig lesen oder verändern kann. Das bedeutet nicht, dass die Festplatte nicht ausfallen, ein Administrator keine Datei löschen oder das Betriebssystem nicht kompromittiert werden kann. Es schränkt einen Angriffsweg ein: das Umschreiben eines ausgewählten Teils der Historie, nachdem der Angreifer ihn gesehen hat.
Diese Unterscheidung beeinflusst die Testfälle. Bei gewöhnlichem Dateizugriff solltest du Löschen plus Neuberechnung testen, weil ein Angreifer die Daten lesen und Hashes berechnen kann. Bei einem schreibblinden Speicher solltest du prüfen, ob ein Aufrufer Löschung, Ersetzung, Rollback oder ein zweites Log unter derselben Identität anfordern kann. Prüfe außerdem, wie der Prüfer das beabsichtigte Log identifiziert. Eine perfekte Kette aus der falschen Datei ist weiterhin der falsche Beleg.
Der häufigste Fehler besteht darin, Speicherberechtigungen mit einem kryptografischen Anker gleichzusetzen. Berechtigungen können von einem ausreichend privilegierten Angreifer geändert werden. Sie bleiben wichtig, weil sie beiläufige Schäden reduzieren und festlegen, welche Prozesse handeln dürfen. Sie ersetzen jedoch keinen Checkpoint, der eine vom Angreifer nicht kontrollierte Grenze überschritten hat.
Teste Rollback getrennt von Kürzung
Rollback sieht aus wie eine Kürzung am Ende mit einer plausiblen älteren Datei. Nach einem Absturz, einer Wiederherstellung aus einem Backup oder einem absichtlichen Austausch kann ein Rechner das gestrige gültige Audit-Log zurückholen. Die wiederhergestellte Datei besteht die interne Prüfung, weil sie gestern tatsächlich gültig war.
Dein Checkpoint erkennt das, wenn er einen neueren Kopf enthält. Vergleiche die Kandidatendatei mit dem neuesten aufbewahrten Checkpoint, nicht mit dem ältesten, den du zufällig findest. Ein Kettenprüfer kann nicht ableiten, welche gültige Version aktuell sein sollte.
Teste es direkt:
- Speichere
audit.jsonlund seinen Checkpoint mit 12 Datensätzen. - Erzeuge eine weitere Testdatei mit mehr Datensätzen und bewahre ihren neueren Checkpoint auf.
- Ersetze die neuere Datei durch die Kopie mit 12 Datensätzen.
- Prüfe die wiederhergestellte Datei intern und vergleiche sie anschließend mit dem neueren Checkpoint.
Erwarte zwei unterschiedliche Ergebnisse. Die interne Prüfung sollte erfolgreich sein. Der Checkpoint-Vergleich sollte fehlschlagen, weil die Datei bei einer älteren Sequenz und einem älteren Digest endet. Schlagen beide Prüfungen fehl, hat dein Testobjekt möglicherweise Bytes verändert, statt einen Rollback nachzubilden. Sind beide erfolgreich, vergleichst du wahrscheinlich mit dem falschen Checkpoint oder hast keinen aufbewahrt.
«Behebe» einen Rollback nicht, indem du neue Datensätze an die ältere Datei anhängst und weitermachst. Sichere zuerst den Zustand. Sobald du neue Datensätze anhängst, vermischst du möglicherweise fehlende Historie mit Aktivitäten nach dem Vorfall. Beginne ein neues Logsegment mit einer dokumentierten Vorfallsgrenze oder befolge das bereits freigegebene Aufbewahrungs- und Wiederherstellungsverfahren deiner Organisation.
Mache Prüfergebnisse während einer Untersuchung brauchbar
Ein Prüfer, der nur invalid zurückgibt, verursacht unnötige Arbeit. Er sollte die erste fehlgeschlagene Bedingung nennen, ohne vertrauliche Nutzdaten auszugeben. Sequenznummer, Byte-Offset oder Zeilennummer, erwarteter und beobachteter Vorgänger-Digest sowie der berechnete Datensatz-Digest liefern normalerweise genügend Details.
Vermeide entschlüsselte Inhalte in Fehlermeldungen. Ein Prüfwerkzeug läuft oft in CI, einem Support-Bundle oder einer Terminalaufzeichnung. Wenn ein verschlüsseltes Audit-Design bei jeder fehlgeschlagenen Prüfung Klartext preisgibt, wird aus einem Integritätsvorfall eine Datenoffenlegung.
Eine disziplinierte Reaktion auf eine fehlgeschlagene Prüfung folgt einer kurzen Reihenfolge:
- Bewahre die Originaldatei auf und erfasse einen Digest dieser Kopie.
- Sammle den neuesten Checkpoint, frühere Checkpoints und alle externen Exporte.
- Prüfe Kopien und speichere die exakte Befehlsausgabe.
- Vergleiche den gemeldeten Kopf mit jedem aufbewahrten Checkpoint.
- Ermittle, ob es sich um Beschädigung, eine Lücke in der Mitte, Verlust am Ende, Rollback oder eine umgeschriebene Kette handelt, die einem Zeugen widerspricht.
Die Einordnung ist wichtig. Ein Fehler wegen einer Lücke in der Mitte bedeutet, dass die Datei einen internen Widerspruch enthält. Eine gültige, aber kürzere Kette kann nur bis zu ihrem letzten Datensatz vollständig sein. Eine gültige Kette, die einem späteren Checkpoint widerspricht, liefert einen Hinweis auf Rollback, Kürzung oder Austausch. Eine umgeschriebene Kette kann intern sauber aussehen, widerspricht aber einem älteren unabhängigen Kopf.
Versprich nicht mehr, als die Belege tragen. «Die Audit-Kette wurde bis Sequenz 90 geprüft und stimmt nicht mit dem aufbewahrten Checkpoint für Sequenz 100 überein» ist präzise und belastbar. «Niemand hat das Log verändert» ist es nicht.
Der entscheidende Test betrifft deine tatsächliche Grenze
Führe zuerst die wegwerfbaren Tests zum Löschen einzelner Zeilen aus, weil sie die Grundlagen vermitteln. Führe anschließend dieselben Fälle mit dem echten Audit-Export und seinem echten Prüfer aus, anhand von Kopien und den dokumentierten Manipulationsgrenzen des Formats. Bearbeite ein produktives verschlüsseltes Log nicht direkt, nur um zu sehen, was passiert.
Bewahre für Sallyport das ursprüngliche verschlüsselte Log auf und verwende sp audit verify vor und nach jeder kontrollierten Änderung auf einer Kopie. Notiere, ob der Prüfer eine interne Lücke erkennt, ob eine verkürzte Kopie weiterhin geprüft werden kann und ob der aufbewahrte Kopf die kürzere Historie sichtbar macht. Die Antwort auf alle drei Fragen ist nützlicher als die pauschale Aussage, das Log sei manipulationssicher.
Eine gültige Kette bedeutet, dass die geprüften Datensätze miteinander übereinstimmen. Eine gültige Kette plus ein vertrauenswürdiger späterer Checkpoint bedeutet, dass die Datensätze einen bekannten Punkt der Geschichte erreichen. Baue und teste für die zweite Aussage, wenn fehlende Aktionen relevant wären.
FAQ
Was beweist die Prüfung eines Audit-Logs mit einer Hash-Kette tatsächlich?
Es beweist, dass die verbliebenen Datensätze ab dem vertrauenswürdigen Startpunkt oder Checkpoint dieselbe Bytefolge bilden, die der Prüfer erwartet. Es beweist nicht, dass niemand ein gültiges Ende entfernt hat, sofern der spätere Kopf nicht an anderer Stelle festgehalten wurde.
Kann eine Hash-Kette erkennen, dass ein Datensatz aus der Mitte gelöscht wurde?
Eine Löschung in der Mitte wird erkannt, wenn jemand den Datensatz einfach entfernt und den folgenden Datensatz unverändert lässt. Dieser verweist weiterhin auf den fehlenden Hash, daher bricht die Kette. Kann ein Angreifer spätere Datensätze umschreiben und eine nicht geschützte Kette neu berechnen, braucht es einen externen Checkpoint, eine Signatur, einen MAC oder ein Speichersystem, das Umschreiben verhindert.
Kann eine Hash-Kette erkennen, dass Datensätze am Ende gelöscht wurden?
Eine reine Kette kann das oft nicht. Liest der Prüfer nur die verkürzte Datei und gibt es keinen gespeicherten späteren Kopf, sieht der letzte verbliebene Datensatz wie das normale Dateiende aus. Ein nach dem gelöschten Datensatz erstellter Checkpoint ändert das: Die verkürzte Datei kann den aufgezeichneten Kopf nicht mehr erreichen.
Verhindert die Verschlüsselung eines Audit-Logs dessen Löschung?
Verschlüsselung verbirgt die Inhalte vor Personen, die die Datei lesen können, aber nicht über das Entschlüsselungsmaterial verfügen. Sie macht die Kette nicht vollständig und hindert einen Angreifer nicht daran, undurchsichtige Ciphertext-Datensätze zu löschen. Integrität und Vertraulichkeit sind getrennte Eigenschaften.
Wo sollten Checkpoints für Audit-Logs gespeichert werden?
Bewahre ihn an einem Ort auf, an dem die Person oder der Prozess, der die Auditdatei ändern kann, ihn nicht unbemerkt ebenfalls ändern kann. Ein signierter Export, ein unabhängiger Collector, ein geschütztes Release-Artefakt oder eine zweite administrative Domäne können geeignet sein. Der Checkpoint muss genug Kontext enthalten, etwa Log-Identität, Sequenznummer, Zeitstempel und Kopf-Hash.
Beweist ein geprüftes Audit-Log, dass jede Aktion aufgezeichnet wurde?
Nein. Eine gültige Kette besagt, dass die verbliebenen Datensätze im Verhältnis zu den geprüften Belegen nicht verändert wurden. Sie zeigt nicht, dass das System jede Aktion aufgezeichnet hat, dass ein kompromittierter Writer kein Ereignis vor dem Protokollieren ausgelassen hat oder dass die Person hinter einem Prozess dazu berechtigt war.
Wie kann ich die Sallyport-Auditprüfung sicher testen?
Verwende vor Änderungen an Kopien genau den Prüfer, der das Log-Format besitzt. Sallyport stellt sp audit verify bereit, sodass ein Team das verschlüsselte Ciphertext-Log offline prüfen kann, ohne dem Prüfer Vault-Material zu geben. Lass das Original unangetastet und notiere Befehl, Dateihash, Testdatum und Ergebnis in den Testnotizen.
Wann sollte ich statt einer Hash-Kette einen Merkle-Baum verwenden?
Eine Hash-Kette verknüpft Datensätze linear. Sie lässt sich einfach erweitern und prüfen, braucht aber einen Anker, um den Verlust am Ende sichtbar zu machen. Ein Merkle-Baum kann für große Logs effiziente Nachweise für Aufnahme und Konsistenz liefern, wie Certificate Transparency beschreibt. Auch dafür müssen Baumköpfe und Zeugen aufbewahrt werden, damit die Historie gegenüber Personen bewiesen werden kann, die ihr Wachstum nicht beobachtet haben.
Was kann mir ein Audit-Prüfer nach einem Fehler sagen?
Er kann zeigen, dass die Bytes nicht zur erwarteten Datensatzfolge passen, und den ersten Datensatz nennen, dessen Vorgängerverweis fehlschlägt. Er kann nicht sagen, wer den Datensatz gelöscht hat, ob die Löschung versehentlich geschah oder ob das Quellsystem ein Ereignis vor dem Schreiben des Logs ausgelassen hat.
Was sollte ich tun, wenn die Prüfung eines verschlüsselten Audits fehlschlägt?
Repariere das Original nicht. Bewahre eine bytegenaue Kopie auf, berechne einen Dateihash, sammle den letzten bekannten Checkpoint und alle exportierten Köpfe und prüfe anschließend Kopien, während du jeden Befehl dokumentierst. Deckt das Log sicherheitsrelevante Aktionen ab, behandle eine fehlgeschlagene Prüfung als untersuchungsbedürftigen Hinweis und nicht als Aufräumfehler.