Wie wird die Seriennummer eines Zertifikats gebildet?

Nachfolgend eine Erklärung, wie die Seriennummern ausgestellter Zertifikate gebildet werden, und wie das Verhalten der Zertifizierungsstellen angepasst werden kann.

Das Verhalten zur Erzeugung von Seriennummern für ausgestellte Zertifikate wird über folgenden Registry-Schlüssel gesteuert:

HKLM\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\{Name-der-Zertifizierungsstelle}\HighSerial

Mit folgendem Befehl kann die aktuelle Konfiguration eingesehen werden:

certutil -getreg CA\HighSerial

Konfigurationsmöglichkeiten

Folgende Konfigurationsmöglichkeiten stehen zur Verfügung:

  • HighSerial gesetzt auf REG_DWORD = 0
  • HighSerial gesetzt auf REG_DWORD zwischen 1 und 0x7f (127)
  • HighSerial gesetzt auf REG_DWORD = 0xffffffff
  • HighSerial gesetzt auf einen hexadezimalen Wert als REG_SZ

Hintergrundinformationen

Um die Funktionsweise der einzelnen Optionen zu verstehen, werden zunächst die drei verwendeten Funktionen kurz erläutert.

GetTickCount

Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days.
The return value is the number of milliseconds that have elapsed since the system was started.

Die Funktion gibt die Zeit seit dem Start des Betriebssystems in Millisekunden, bis zu einem maximalen Wert von 49,7 Tagen zurück.

UShort

Holds unsigned 16-bit (2-byte) integers ranging in value from 0 through 65,535.

Der UShort Datentyp kann die Werte 0 bis 65535 annehmen.

CryptGenRandom

The CryptGenRandom function fills a buffer with cryptographically random bytes.

Die CryptGenRandom Funktion gibt Zufallszahlen zurück.

HighSerial REG_DWORD = 0

Dies ist die Standardeinstelung für alle Zertifizierungsstellen bis Windows Server 2008 R2. Die generierten Seriennummern werden 10 Bytes lang sein und setzen sich wie folgt zusammen:

DWORD GetTickCount() + 
UShort (Schlüsselindex des Zertifizierungsstellenzertifikats) +
DWORD RequestId

Da hier keine echte Zufallskomponentente beinhaltet ist, sind diese Seriennummern vorhersehbar, was einen Angriff auf einen unsicheren Signaturalgorithmus (z.B. MD5 und SHA-1) erleichtert (und im Falle vom Flame auch erfolgreich durchgeführt wurde). Aus diesem Grund verhalten sich Zertifizierungsstellen ab Windows Server 2012 anders.

BeispieL

610dde5a000000000003

Nachdem das Zertifizierungsstellen-Zertifikat mit einem neuen Schlüssel erneuert wurde, sieht man, dass sich das entsprechende Bit verändert hat:

6154e9cb000100000007

HighSerial gesetzt auf REG_DWORD zwischen 1 und 0x7f (127)

Dies ist die Standardeinstellung für alle Zertifizierunsstellen ab Windows Server 2012 (jedoch nicht, wenn diese via In-Place Upgrade von einem früheren Betriebssystem auf diesen Versionsstand gebracht wurde). Die generierten Seriennummern werden 19 Bytes lang sein und setzen sich wie folgt zusammen:

BYTE der konfigurierte Registry-Wert + 
DWORD RequestId +
8 Bytes CryptGenRandom Daten +
UShort (Schlüsselindex des Zertifizierungsstellenzertifikats) +
DWORD RequestId

Die Zufallsdaten werden für jedes ausgestellte Zertifikat erneuert, sodass die generierten Seriennummern nicht vorhersagbar sind.

Die Seriennummern haben darüber hinaus einen Präfix, welcher beispielsweise bei der Auditierung von OCSP-Anfragen ausgewertet werden kann.

Beispiel

HighSerial ist gesetzt auf REG_DWORD = 3b (59). Wie man sieht, beginnt die Seriennummer mit diesem Wert.

3b000000031e83d411d8bcef0f000000000003

HighSerial gesetzt auf REG_DWORD = 0xffffffff

Wenn die Zertifizierungsstelle die erste Seriennummer zu generieren versucht, wird eine 8 Byte große Zufallszahl mittels der CryptGenRandom Funktion erzeugt und im HighSerial Wert abgespeichert. Die generierten Seriennummern werden 14 Bytes lang sein und setzen sich wie folgt zusammen:

8 Bytes die zuvor generierten CryptGenRandom Daten aus HighSerial +
UShort (Schlüsselindex des Zertifizierungsstellenzertifikats) +
DWORD RequestId

Da die 8 Bytes Zufallsdaten nur beim ersten Ausstellen eines Zertfikats generiert werden, sind diese Seriennummern vorhersagbar. Die Option sollte daher nicht verwendet werden.

Beispiel

16a28b7e63099507000000000004

Der mittels CryptGenRandom generierte Zufallswert ist im HighSerial Wert als REG_SZ (String) eingetragen:

Highserial gesetzt auf einen hexadezimalen Wert als REG_SZ

Es kann ein 1 bis 13 Bytes langer hexadezimaler Wert vom Typ REG_SZ in den HighSerial Wert eingetragen werden. Die generierten Seriennummern werden – je nach länge des konfigurierten eingestelltem Wertes – zwischen 7 bis 19 Bytes lang sein und setzen sich wie folgt zusammen:

1 bis 13 Bytes der in HighSerial eingetragenen Daten +
UShort (Schlüsselindex des Zertifizierungsstellenzertifikats) +
DWORD RequestId

Auch diese Option enthält keine Funktion zum Erzeugen zufälliger Werte und führt daher zu vorhersagbaren Seriennummern. Sie sollte daher nicht verwendet werden.

Standardwerte

BetriebssystemStandardwert
Windows Server 2003
Windows Server 2008
Windows Server 2008 R2
REG_DWORD = 0
Windows Server 2012
Windows Server 2012 R2
Windows Server 2016
Windows Server 2019
REG_DWORD zufällig erzeugt zwischen 1 und 0x7f (127)

Fazit

Aus Sicherheits-Sicht sollte immer die Konfiguration mit dem höchsten Zufallsanteil gewählt werden. Dies entspricht der Option, den Wert HighSerial als REG_DWORD auf einen Wert zwischen 1 und 0x7f (127) zu setzen, wie es seit Windows Server 2012 der Standard ist.

Bei Systemen, die mittels In-Place Upgrade auf Windows Server 2012 oder neuer migriert wurden, kann es sinnvoll sein, den HighSerial Wert auf den neuen Standard zu setzen.

Bei Systemen, die auf einen Server mit einem neuem Betriebssystem migriert wurden, sollte aktiv eine Entscheidung getroffen werden, ob man beim Import der Registrierung den Wert vom Altsystem übernimmt oder bei der neuen Einstellung belässt.

Es ist jedoch auch möglich, Zertifizierungsstellen, die auf Windows Server 2008 und Windows Server 2008 R2 laufen, bereits auf den neuen Standardwert von Windows Server 2012 anzuheben.

Weiterführende Links:

Externe Quellen

de_DEDeutsch