(Massenhaftes) Löschen von Einträgen in der Zertifizierungsstellen-Datenbank (Zertifikate, Anforderungen, Sperrlisten)

Manchmal kommt es vor, dass die Datenbank der Zertifizierungsstelle extrem groß wird. Vielleicht sind unbemerkt sehr viele Zertifikatanforderungen eingetroffen und abgelehnt worden, vielleicht befinden sich auch viele Zertifikate in der Datenbank, die doppelt ausgestellt wurden. Bevor die Zertifizierungsstellen-Datenbank kompaktiert werden kann, müssen diese Einträge zuerst gelöscht werden, um den Speicherplatz in der Datenbank wieder freizugeben.

Eine Löschung von Einträgen ist mit dem -deleterow Schalter des certutil-Programms möglich.

certutil [Options] -deleteRow ROWID | Date [Request | CERT | Ext | Attrib | CRL

Nachfolgend einige Beispiele zur Benutzung von certutil mit dem -deleterow Schalter.

Es wird empfohlen, vor der Löschung von Einträgen die Zertifizierungsstelle in den Warungsmodus zu versetzen, sodass keine neuen Zertifikate beantragt werden können, und ein aktuelles Backup der Zertifizierungsstellen-Datenbank zu erstellen.

Löschen einzelner Zeilen

Einzelne Zeilen innerhalb der Zertifizierungsstellen-Datenbank können – identifiziert anhand der Zeilennummer (Row ID) mit folgendem Befehl gelöscht werden:

certutil -deleterow <RowId> 

Löschen von fehlgeschlagenen Anforderungen

Eine Löschung von fehlgeschlagenen Anforderungen ist mit folgender Syntax möglich:

certutil -deleterow <Datum> Request 

Das Datum beschreibt im Falle der Anforderungen den Zeitpunkt, zu welchem die Anforderung an die Zertifizierungsstelle gesendet wurde.

Das Datum muss im lokalen Format (Regionseinstellung des Computers, auf dem der Befehl ausgeführt wird), angegeben werden.

Um das korrekte Datumsformat zu ermitteln, kann folgender PowerShell-Befehl verwendet werden:

$((Get-Date).ToString($(Get-culture).DateTimeFormat.ShortDatePattern)) 

Mit diesem kann auch gerechnet werden. Hier ein Beispiel um das lokale Datum vor 180 Tagen zu ermitteln:

$((Get-Date).AddDays(-180).ToString($(Get-culture).DateTimeFormat.ShortDatePattern)) 

Bei sehr großen Datensätzen wird die Datenbankabfrage nach einer Weile in einen Timeout laufen. Certutil wird dann den Fehlercode -939523027 zurückgeben. Dies kann umgangen werden, indem man den Befehl in einer Batchdatei in eine Schleife setzt.

@echo off
:Top
certutil -deleterow <Datum> Request
If %ERRORLEVEL% EQU -939523027 goto Top 

Löschen aller abgelaufenen Zertifikate ab einem bestimmten Datum

Wichtig: Dieser Befehl löscht alle abgelaufenen Zertifikate, was in den meisten Fällen nicht erwünscht ist. Wie man präzisere Kriterien formuliert wird im weiteren Verlauf des Beitrags erklärt.

Eine Löschung von abgelaufenen Zertifikaten ist mit folgender Syntax möglich:

certutil -deleterow <Datum> Cert

Hier beschreibt das Datum das Ablaufdatum (NotAfter) des Zertifikats.

Zu beachten ist, dass das Datum in der Vergangenheit liegen muss. Eine Löschung noch gültiger Zertifikate ist auf diese Weise nicht möglich.

Auch hier gilt es zu beachten, dass bei sehr großen Datensätzen die Datenbankabfrage nach einer Weile in einen Timeout laufen wird. Hier ein entsprechend angepasstes Beispiel für abgelaufene Zertifikate.

@echo off
:Top
certutil -deleterow <Datum> Cert
If %ERRORLEVEL% EQU -939523027 goto Top 

Löschen bestimmter Sperrlisten

Die Identifikation und Löschung bestimmter Sperrlisten ist im Artikel "Einsicht in die Sperrlisten-Tabelle der Zertifizierungsstellen-Datenbank" beschrieben.

Löschen von Zertifikaten nach bestimmten Kriterien

Die vorigen Beispiele sind was die Suchkriterien angeht leider nicht für alle Fälle geeignet. Zudem funktionieren sie bei größeren Datenbanken nur mit Behelfsmitteln, da es einen Timeout-Wert gibt, nachdem Datenbankabfragen beendet werden.

Um beides zu umgehen, bietet es sich an, zunächst eine präzise Datenbankabfrage zu formulieren und diese zwischenzuspeichern. Das Zwischenspeichern ist aufgrund des Timeout-Problems erforderlich, eine direkte Verarbeitung in einer Pipeline wäre zwar möglich, würde aber auch nach einer Weile abgebrochen werden.

Hier ein Beispiel-Befehl, um zu einem bestimmten Datum abgelaufene Zertifikate von einer bestimmten Zertifikatvorlage zu identifizieren und die Anforderungs-IDs in einer CSV-Datei zu speichern.

certutil ^
-view ^
-restrict "CertificateTemplate=<OID-der-Vorlage>,NotAfter=<Datum>" ^
-out "RequestId" ^
csv > <Pfad-zur-Datei>.csv

Die Zertifikatvorlage wird anhand ihres Objekt Identifiers identifiziert, welcher sich beispeilsweise aus der Certificate Template Information Erweiterung eines der Zertifikate ermitteln lässt.

Die erzeugte Datei sollte nun die entsprechenden Einträge beinhalten. Wichtig ist, den exakten Namen der Kopfzeile zu ermitteln, dieser unterscheidet je nach eingestellter Betriebssystem-Sprache.

Im nächsten Schritt wird die CSV-Datei via PowerShell eingelesen und für jeden Eintrag eine Löschung veranlasst.

Import-Csv -Path <Pfad-zur-Datei>.csv | ForEach-Object -Process {
certutil -deleterow $_."Issued Request ID"
}

Diese Methode ist zwar potentiell langsamer als die zuvor genannten, dafür können Abfragen präziser formuliert werden, und es besteht keine Gefahr, dass die Datenbanksitzung in einen Timeout läuft, da jede Löschung einer Zeile eine eigenständige Datenbankoperation darstellt.

Bevor die Löschung ausgelöst wird, sollten die Ergebnisse genau geprüft werden, um nicht die falschen Zertifikate zu löschen.

Kompaktieren der CA-Datenbank

Nun kann die Datenbank der Zertifizierungsstelle kompaktiert werden. Die genauen Schritte hierfür sind im Artikel 2Kompaktieren (Defragmentieren) der Zertifizierungsstellen-Datenbank" beschrieben.

Trivia

Ist die Überwachung von Auditereignissen aktiviert, wird die Zertifizierungsstelle eine Löschung in das Sicherheits-Ereignisprotokoll (Ereignis Nr. 4896) schreiben.

Weiterführende Links:

Externe Quellen