Zum Inhalt springen
ecdsa.com
← Alle Artikel

X.509-Zertifikatsfelder an echten Zertifikaten erklärt

Wir haben am 20. Oktober 2026 die Ketten von letsencrypt.org, github.com und one.one.one.one abgerufen und sie mit OpenSSL 3.6.5 Feld für Feld gelesen – Seite an Seite mit RFC 5280 und den Baseline Requirements 2.3.1 des CA/Browser Forums, die festlegen, was jedes Feld enthalten muss.

Kurz gesagt. Ein TLS-Client identifiziert einen Server ausschließlich über den Subject Alternative Name: die Einträge dNSName und iPAddress, nie über den Common Name des Subjects. Key Usage legt fest, was der Schlüssel mathematisch tun darf (signieren, verschlüsseln, Zertifikate signieren), Extended Key Usage legt fest, für welche Anwendung (serverAuth, clientAuth, Codesignatur). Erst Basic Constraints mit CA:TRUE erlaubt einem Zertifikat, weitere Zertifikate auszustellen; ein Leaf-Zertifikat hat CA:FALSE. Authority und Subject Key Identifier sind Hinweise, die einem Client helfen, den Aussteller zu finden, keine Sicherheitsprüfungen. CRL Distribution Points und Authority Information Access sagen einem Client, wo er den Widerruf prüfen und ein fehlendes Zwischenzertifikat abrufen kann; Zertifikate von Let's Encrypt enthalten keine OCSP-URL mehr. SCTs belegen, dass das Zertifikat in den Logs von Certificate Transparency eingetragen wurde. Das verlangen Chrome und Safari.

Ein echtes Zertifikat zum Untersuchen abrufen

openssl s_client -showcerts gibt jedes Zertifikat aus, das der Server sendet; openssl x509 -text dekodiert eines davon. Der Testaufbau lief in debian:forky-20261005-slim mit OpenSSL 3.6.5 und pyca/cryptography 49.0.0:

Vom Server gesendete Kette speichern, eine PEM-Datei pro Zertifikat
openssl s_client -connect letsencrypt.org:443 -servername letsencrypt.org -showcerts </dev/null 2>/dev/null \
  | awk '/-----BEGIN CERTIFICATE-----/{n++; f=sprintf("letsencrypt.org-%d.pem", n); p=1} p{print >> f} /-----END CERTIFICATE-----/{p=0; close(f)}'
openssl x509 -in letsencrypt.org-1.pem -noout -text

-servername sendet SNI; ohne SNI liefern viele Server ein Standardzertifikat für einen anderen Namen aus. Das Leaf-Zertifikat von letsencrypt.org, wie es an diesem Tag ausgeliefert wurde (der öffentliche Schlüssel ist vollständig abgebildet, die beiden SCT-Signaturen sind gekürzt):

openssl x509 -text, Leaf-Zertifikat von letsencrypt.org (SCT-Signaturen gekürzt)
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            05:43:93:3b:e3:86:b3:a2:b3:ad:d5:34:f2:10:3b:c8:b6:5f
        Signature Algorithm: ecdsa-with-SHA384
        Issuer: C=US, O=Let's Encrypt, CN=YE2
        Validity
            Not Before: Sep  4 14:34:32 2026 GMT
            Not After : Dec  3 14:34:31 2026 GMT
        Subject: CN=letsencrypt.org
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:e9:e5:40:7b:43:1e:46:b9:8e:45:e4:aa:cb:40:
                    ab:e6:3f:99:27:b8:b7:81:e3:32:56:e7:14:74:5f:
                    fa:43:5b:52:c6:a6:b5:66:c5:56:0e:07:21:56:e3:
                    4c:fe:35:55:4f:f0:92:2f:eb:22:4a:f1:7a:39:51:
                    39:04:c2:b3:0d
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier: 
                16:68:8D:1E:2A:32:48:8C:B5:F1:10:0A:16:08:37:08:3B:9D:30:23
            X509v3 Authority Key Identifier: 
                B9:59:F2:8E:CF:22:F0:86:D3:37:48:FF:76:14:18:BA:82:D8:55:87
            Authority Information Access: 
                CA Issuers - URI:http://ye2.i.lencr.org/
            X509v3 Subject Alternative Name: 
                DNS:cp.letsencrypt.org, DNS:cp.root-x1.letsencrypt.org, DNS:cps.letsencrypt.org, DNS:cps.root-x1.letsencrypt.org, DNS:lencr.org, DNS:letsencrypt.com, DNS:letsencrypt.org, DNS:www.lencr.org, DNS:www.letsencrypt.com, DNS:www.letsencrypt.org
            X509v3 Certificate Policies: 
                Policy: 2.23.140.1.2.1
            X509v3 CRL Distribution Points: 
                Full Name:
                  URI:http://ye2.c.lencr.org/96.crl

            CT Precertificate SCTs: 
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : D8:09:55:3B:94:4F:7A:FF:C8:16:19:6F:94:4F:85:AB:
                                B0:F8:FC:5E:87:55:26:0F:15:D1:2E:72:BB:45:4B:14
                    Timestamp : Sep  4 15:33:02.377 2026 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                                30:46:02:21:00:D0:2E:25:A4:9D:7F:C8:18:D6:7B:5E:...
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 46:AF:86:3D:3B:3E:E5:9F:A5:77:DE:A8:24:5D:36:B0:
                                D9:ED:22:A2:23:F4:61:77:41:22:94:52:EE:95:50:5F
                    Timestamp : Sep  4 15:33:02.552 2026 GMT
                    Extensions: 00:00:05:00:24:DF:DB:0C
                    Signature : ecdsa-with-SHA256
                                30:44:02:20:31:2F:83:D6:42:65:26:0D:58:D7:DD:C3:...
    Signature Algorithm: ecdsa-with-SHA384
    Signature Value:
        30:65:02:31:00:ee:1d:b0:7c:35:88:98:15:57:b8:88:73:23:
        92:a9:bf:40:bf:e8:ae:02:48:e6:f4:7a:2d:18:fc:43:52:d3:
        80:9a:ff:ce:e0:2a:0d:4a:29:e6:80:a2:94:f5:4f:14:d9:02:
        30:35:08:99:3b:bc:89:5b:23:a0:ef:64:24:e2:b2:b3:b8:c2:
        d8:d5:95:45:de:f3:03:e8:e7:82:78:a5:9e:c2:1f:ad:eb:14:
        fc:39:51:c7:e1:18:e9:16:b4:a5:48:de:09

Die folgenden Abschnitte gehen es von oben nach unten durch. Die Struktur selbst definiert RFC 5280 (§4.1 für die Felder, §4.2 für die Erweiterungen); was ein öffentlich vertrauenswürdiges TLS-Zertifikat enthalten darf, regeln die Baseline Requirements (BR) des CA/Browser Forums, Version 2.3.1 vom 4. Oktober 2026, §7.1.

Version, Seriennummer, Signaturalgorithmus, Gültigkeit

  • Version 3 ist die einzige Version mit Erweiterungen; die BR schreiben sie vor.
  • Seriennummer. Eindeutig pro Aussteller und bei öffentlichen CAs „eine nicht fortlaufende Zahl größer als null (0) und kleiner als 2¹⁵⁹, die mindestens 64 Bit Ausgabe eines CSPRNG enthält“ (BR §7.1.2.7). Der Zufall schützt hier vor Chosen-Prefix-Kollisionsangriffen auf den Hash der Signatur; deshalb sehen Seriennummern wie Rauschen aus. Eine Seriennummer ist das, was CRLs auflisten.
  • Der Signaturalgorithmus steht zweimal im Zertifikat, im signierten Teil und neben der Signatur, und beide Angaben müssen Byte für Byte identisch sein. ecdsa-with-SHA384 sagt hier etwas über den Schlüssel des Ausstellers aus (YE2 hat einen P-384-Schlüssel), nicht über den des Subjects. Der Signaturwert am Ende ist eine ECDSA-Signatur in DER, dem Format, das ECDSA-Signaturformate erklärt.
  • Gültigkeit. notBefore und notAfter sind inklusiv. Dieses Zertifikat ist 90 Tage gültig; das Maximum nach den BR liegt bei 200 Tagen für Zertifikate, die seit dem 15. März 2026 ausgestellt werden, bei 100 Tagen ab dem 15. März 2027 und bei 47 Tagen ab dem 15. März 2029 (BR §6.3.2). Let's Encrypt stellt in seinem Opt-in-Profil tlsserver bereits 45-Tage-Zertifikate aus und plant, seinen Standard am 10. Februar 2027 auf 64 Tage und am 16. Februar 2028 auf 45 Tage umzustellen.

Subject und Subject Alternative Name

Das Subject ist ein Distinguished Name: hier nur CN=letsencrypt.org. Domain-validierte Zertifikate enthalten nichts weiter, weil die CA nichts weiter validiert hat. Die Namen, die ein Client prüft, stehen im Subject Alternative Name (SAN): bei diesem Zertifikat zehn Einträge vom Typ DNS:.

Der Common Name zählt schon lange nicht mehr. RFC 9525 (2023), der RFC 6125 ersetzt hat, sagt: „Der Common-Name-RDN DARF NICHT (MUST NOT) verwendet werden, um einen Dienst zu identifizieren.“ Chrome gleicht ihn seit Version 58 (2017) nicht mehr ab, und Go lehnt Zertifikate, die nur einen CN haben, mit x509: certificate relies on legacy Common Name field ab. Die BR behalten den CN nur als Kopie: Ist er vorhanden, „MUSS er genau einen Eintrag enthalten, der einem der Werte in der Erweiterung subjectAltName des Zertifikats entspricht“ (§7.1.4.3).

Ein SAN kann auch IP-Adressen enthalten. Das Zertifikat des Resolvers von Cloudflare:

openssl x509 -noout -subject -ext subjectAltName (Leaf-Zertifikat von one.one.one.one)
subject=C=US, ST=California, L=San Francisco, O=Cloudflare, Inc., CN=cloudflare-dns.com
X509v3 Subject Alternative Name: 
    DNS:cloudflare-dns.com, DNS:*.cloudflare-dns.com, IP Address:1.0.0.1, IP Address:1.1.1.1, IP Address:162.159.36.1, IP Address:162.159.46.1, IP Address:2606:4700:4700:0:0:0:0:1001, IP Address:2606:4700:4700:0:0:0:0:1111, IP Address:2606:4700:4700:0:0:0:0:64, IP Address:2606:4700:4700:0:0:0:0:6400, DNS:one.one.one.one

https://1.1.1.1 funktioniert, weil 1.1.1.1 als Eintrag vom Typ iPAddress enthalten ist; ein Eintrag DNS:1.1.1.1 würde nicht auf eine IP-Adresse passen. Genau darum geht es bei der Go-Meldung cannot validate certificate for … because it doesn't contain any IP SANs. Das Subject enthält hier außerdem Organisation und Ort, und das Zertifikat weist die OV-Richtlinie 2.23.140.1.2.2 aus (siehe DV vs. OV vs. EV); der Browser zeigt nichts davon an. Es wurde am 31. Dezember 2025 für 355 Tage ausgestellt, bevor die 200-Tage-Grenze in Kraft trat.

Eine Wildcard wie *.cloudflare-dns.com deckt genau ein Label ab: a.cloudflare-dns.com, aber weder cloudflare-dns.com selbst noch a.b.cloudflare-dns.com (RFC 9525 §6.3). OpenSSL prüft Namen genauso:

openssl x509 -noout -checkhost <name> (Leaf-Zertifikat von letsencrypt.org)
Hostname www.lencr.org does match certificate
Hostname lencr.org.evil.test does NOT match certificate
Hostname mail.letsencrypt.org does NOT match certificate

Subject Public Key Info

Das Feld subjectPublicKeyInfo (SPKI) enthält den Algorithmus und den Schlüssel: einen unkomprimierten Punkt auf P-256 (04, gefolgt von den je 32 Byte langen Koordinaten x und y). Es ist der einzige Teil des Zertifikats, auf den sich der private Schlüssel des Subjects bezieht. Deshalb bildet Public-Key-Pinning den Hash über den SPKI statt über das ganze Zertifikat: Eine Erneuerung mit demselben Schlüssel behält den Pin (siehe Certificate Pinning 2026).

Key Usage und Extended Key Usage

Zwei verschiedene Fragen:

  • Key Usage (RFC 5280 §4.2.1.3) beschränkt die kryptografischen Operationen des Schlüssels: digitalSignature, keyEncipherment, keyAgreement, keyCertSign, cRLSign und einige seltenere Bits. Für ein ECDSA-Leaf-Zertifikat verlangen die BR digitalSignature und verbieten keyEncipherment (ein EC-Schlüssel kann nicht verschlüsseln). Ein RSA-Leaf-Zertifikat darf zusätzlich keyEncipherment für den alten RSA-Schlüsselaustausch von TLS 1.2 enthalten; die BR nennen das Unterstützung für „unsichere Cipher Suites“. Außerdem sagen die BR, die Erweiterung SOLLTE (SHOULD) vorhanden und als kritisch markiert sein, wie hier.
  • Extended Key Usage (§4.2.1.12) benennt Anwendungen: serverAuth (1.3.6.1.5.5.7.3.1), clientAuth (…3.2), codeSigning (…3.3), emailProtection (…3.4), timeStamping (…3.8). Ein TLS-Serverzertifikat MUSS serverAuth enthalten und DARF NICHT Codesignatur, E-Mail, Zeitstempel, OCSP-Signatur oder anyExtendedKeyUsage enthalten (BR §7.1.2.7.10).

Bei clientAuth hat sich etwas geändert. Die BR erlauben es weiterhin (MAY), aber die Chrome Root Program Policy 1.8 verlangt Hierarchien, die „der TLS-Server-Authentifizierung vorbehalten“ sind: Untergeordnete CAs, die ab dem 15. Juni 2026 offengelegt werden, dürfen nur serverAuth ausweisen, und Subscriber-Zertifikate, die ab dem 15. März 2027 ausgestellt werden, ebenfalls. Let's Encrypt hat clientAuth am 11. Februar 2026 aus seinem Standardprofil entfernt und am 8. Juli 2026 ganz aufgehört, es auszustellen; das Leaf-Zertifikat von letsencrypt.org oben enthält nur serverAuth. Wenn dein Dienst Clients mit öffentlichen TLS-Zertifikaten authentifiziert hat, braucht er eine private CA (siehe mTLS erklärt).

Verifizierer setzen die EKU durch. Ein Test mit einer Wegwerf-CA und einem Zertifikat, dessen EKU nur clientAuth enthält:

openssl verify -CAfile root.pem -purpose sslserver worker-7.pem, danach -purpose sslclient
CN=worker-7
error 26 at 0 depth lookup: unsuitable certificate purpose
error worker-7.pem: verification failed
worker-7.pem: OK

Das ist Fehler 26 von OpenSSL; Go meldet denselben Zustand als x509: certificate specifies an incompatible key usage.

Basic Constraints: wer Zertifikate ausstellen darf

Die Erweiterung Basic Constraints enthält einen booleschen Wert und eine Zahl. CA:TRUE erlaubt dem Schlüssel des Zertifikats, andere Zertifikate zu signieren; pathlen begrenzt, wie viele Zwischen-CAs darunter noch folgen dürfen. RFC 5280 §4.2.1.9 sagt ausdrücklich, dass ohne gesetztes cA „der zertifizierte öffentliche Schlüssel NICHT zur Prüfung von Zertifikatssignaturen verwendet werden DARF (MUST NOT)“. Die Kette von letsencrypt.org aufwärts:

ZertifikatBasic ConstraintsKey Usage
CN=letsencrypt.orgkritisch, CA:FALSEDigital Signature
CN=YE2 (Zwischenzertifikat)kritisch, CA:TRUE, pathlen:0Digital Signature, Certificate Sign, CRL Sign
CN=Root YE (cross-signiert von ISRG Root X2)kritisch, CA:TRUECertificate Sign, CRL Sign

pathlen:0 bei YE2 bedeutet, dass YE2 nur Leaf-Zertifikate ausstellen kann. Um die Durchsetzung zu sehen, signierte der Testaufbau mit dem Schlüssel eines gewöhnlichen Serverzertifikats (CA:FALSE, Key Usage digitalSignature) ein weiteres Zertifikat:

openssl verify -CAfile root.pem -untrusted api.example.test.pem forged.example.test.pem
CN=api.example.test
error 79 at 1 depth lookup: invalid CA certificate
CN=api.example.test
error 32 at 1 depth lookup: key usage does not include certificate signing
error forged.example.test.pem: verification failed

Beide Regeln greifen: Fehler 79 für das fehlende CA:TRUE und Fehler 32 für das fehlende keyCertSign. Weil Internet Explorer genau diese Prüfung ausließ, akzeptierte er 2002 jedes Leaf-Zertifikat als CA. Python 3.13 und neuer aktivieren außerdem den strikten Modus von OpenSSL, der zusätzlich CA-Zertifikate ablehnt, deren Basic Constraints nicht als kritisch markiert sind.

Authority und Subject Key Identifier

Der Subject Key Identifier benennt den eigenen Schlüssel des Zertifikats, der Authority Key Identifier den Schlüssel, der es signiert hat. Jeder AKI entspricht dem SKI des nächsthöheren Zertifikats:

Subject, SKI und AKI jedes Zertifikats, das letsencrypt.org sendet
  subject=CN=letsencrypt.org
  16:68:8D:1E:2A:32:48:8C:B5:F1:10:0A:16:08:37:08:3B:9D:30:23
  B9:59:F2:8E:CF:22:F0:86:D3:37:48:FF:76:14:18:BA:82:D8:55:87
  subject=C=US, O=Let's Encrypt, CN=YE2
  B9:59:F2:8E:CF:22:F0:86:D3:37:48:FF:76:14:18:BA:82:D8:55:87
  A3:C8:26:5A:8E:A1:4C:D0:35:63:FC:9B:23:C8:3A:AE:56:F3:4F:56
  subject=C=US, O=ISRG, CN=Root YE
  A3:C8:26:5A:8E:A1:4C:D0:35:63:FC:9B:23:C8:3A:AE:56:F3:4F:56
  7C:42:96:AE:DE:4B:48:3B:FA:92:F8:9E:8C:CF:6D:8B:A9:72:37:95
  subject=C=US, O=Internet Security Research Group, CN=ISRG Root X2
  7C:42:96:AE:DE:4B:48:3B:FA:92:F8:9E:8C:CF:6D:8B:A9:72:37:95
  79:B4:59:E6:7B:B6:E5:E4:01:73:80:08:88:C8:1A:58:F6:E9:9B:6E

Schlüsselkennungen helfen einem Verifizierer, den richtigen Aussteller zu wählen, wenn sich mehrere CA-Zertifikate einen Namen teilen (CAs nach einem Schlüsselwechsel oder cross-signierte CAs, etwa die beiden existierenden Zertifikate von ISRG Root X2). Beweisen können sie nichts: Das leistet die Signaturprüfung. RFC 5280 verlangt den AKI in jedem Zertifikat außer in selbstsignierten Root-Zertifikaten und den SKI in jedem CA-Zertifikat; RFC 5280 schlägt einen SHA-1-Hash des Schlüssels als eine Möglichkeit vor, den SKI zu berechnen, Aussteller dürfen aber jeden eindeutigen Wert verwenden. Die BR stufen den SKI im Leaf-Zertifikat als „NICHT EMPFOHLEN“ (NOT RECOMMENDED) ein; Let's Encrypt und Sectigo nehmen trotzdem beide einen auf. Bei strikten Verifizierern schlägt die Prüfung eines CA-Zertifikats ohne AKI fehl, wie Pythons Missing Authority Key Identifier zeigt.

Die Kette zeigt auch, dass der Pfad, den du validierst, nicht immer der Pfad ist, den der Server sendet. letsencrypt.org sendet vier Zertifikate, zuletzt ISRG Root X2, cross-signiert von ISRG Root X1; OpenSSL mit dem Trust Store von Debian hört beim X2-Root auf, dem es bereits vertraut:

openssl verify -show_chain -untrusted untrusted.pem letsencrypt.org-1.pem
letsencrypt.org-1.pem: OK
Chain:
depth=0: CN=letsencrypt.org (untrusted)
depth=1: C=US, O=Let's Encrypt, CN=YE2 (untrusted)
depth=2: C=US, O=ISRG, CN=Root YE (untrusted)
depth=3: C=US, O=Internet Security Research Group, CN=ISRG Root X2

CRL Distribution Points, AIA und OCSP

Zwei Erweiterungen verweisen auf URLs:

  • CRL Distribution Points (RFC 5280 §4.2.1.13): wo der Aussteller seine CRL veröffentlicht. Die BR verlangen die Erweiterung, es sei denn, das Zertifikat ist kurzlebig (seit dem 15. März 2026: höchstens 7 Tage) oder enthält eine OCSP-URL, und die URL muss einfaches http sein: Die CRL ist signiert, TLS brächte also nichts und würde eine Schleife erzeugen.
  • Authority Information Access (§4.2.2.1): CA Issuers gibt an, wo das Zertifikat der ausstellenden CA heruntergeladen werden kann, und OCSP ist der OCSP-Responder des Ausstellers.

Das Leaf-Zertifikat von Let's Encrypt hat eine CRL-URL und keine OCSP-URL: Let's Encrypt hat im Mai 2025 die OCSP-URLs aus seinen Zertifikaten entfernt und am 6. August 2025 seine Responder abgeschaltet, nachdem die BR OCSP optional gemacht hatten. Sectigo betreibt OCSP weiterhin; das Leaf-Zertifikat von github.com enthält beide Zugriffsmethoden und zwei Richtlinien:

openssl x509 -text, Leaf-Zertifikat von github.com (Auszug)
            X509v3 Certificate Policies: 
                Policy: 1.3.6.1.4.1.6449.1.2.2.7
                  CPS: https://sectigo.com/CPS
                Policy: 2.23.140.1.2.1
            Authority Information Access: 
                CA Issuers - URI:http://crt.sectigo.com/SectigoPublicServerAuthenticationCADVE36.crt
                OCSP - URI:http://ocsp.sectigo.com

Die CRL hinter dem Leaf-Zertifikat von letsencrypt.org, heruntergeladen und gegen das Zertifikat von YE2 geprüft:

Die im Zertifikat genannte CRL abrufen und ihre Signatur prüfen
crl=$(openssl x509 -in letsencrypt.org-1.pem -noout -ext crlDistributionPoints | grep -o 'http://[^ ]*')
curl -sS -o leaf.crl "$crl"
openssl crl -inform DER -in leaf.crl -noout -issuer -lastupdate -nextupdate
openssl crl -inform DER -in leaf.crl -noout -text | grep -c 'Serial Number:'
openssl crl -inform DER -in leaf.crl -noout -CAfile letsencrypt.org-2.pem
Ausgabe
issuer=C=US, O=Let's Encrypt, CN=YE2
lastUpdate=Oct 20 15:03:57 2026 GMT
nextUpdate=Oct 29 15:03:56 2026 GMT
1590
verify OK

Die 96.crl in der URL ist ein Shard: Die CA verteilt ihre Widerrufe auf viele kleine CRLs und nennt in jedem Zertifikat die passende, sodass ein Client 1.590 Einträge herunterlädt statt aller Widerrufe. Browser rufen CRLs selten live ab; Chrome und Firefox verteilen Widerrufsdaten selbst per Push an die Clients. Die Abwägungen stehen in CRL vs. OCSP.

CA Issuers wird wichtig, wenn ein Server vergisst, sein Zwischenzertifikat mitzusenden. Browser und die Plattform-Verifizierer von Windows und macOS folgen dem Verweis („AIA-Chasing“); OpenSSL (und damit curl, Python und PHP unter Linux), Go unter Linux und Java mit Standardeinstellungen tun das nicht. Derselbe falsch konfigurierte Server funktioniert deshalb im Browser und scheitert im Code mit „unable to get local issuer certificate“.

Certificate Policies

Jedes öffentliche TLS-Zertifikat weist genau eine Richtlinienkennung des CA/Browser Forums aus, die angibt, wie das Subject validiert wurde: 2.23.140.1.2.1 für Domain-Validierung, 2.23.140.1.2.2 für Organisationsvalidierung, 2.23.140.1.2.3 für die Validierung einer Einzelperson, 2.23.140.1.1 für Extended Validation (BR §7.1.6.1). CAs ergänzen eigene Richtlinien-OIDs und einen Link auf ihr Practice Statement (CPS), wie Sectigo oben. Clients, die Validierungsstufen anzeigen, lesen diese Erweiterung, nicht das Subject.

Signed Certificate Timestamps

Vor der Ausstellung reicht die CA ein Präzertifikat (derselbe Inhalt mit einer Poison-Erweiterung) bei den Logs von Certificate Transparency ein, und jedes Log antwortet mit einem signierten Versprechen, es zu veröffentlichen: dem SCT. Die CA bettet diese SCTs in das endgültige Zertifikat ein (OID 1.3.6.1.4.1.11129.2.4.2, RFC 6962 §3.3). Die Log-ID ist ein Hash des Log-Schlüssels; die Log-Liste von Chrome ordnet ihr einen Namen zu:

scts.py: CT-Logs hinter jedem eingebetteten SCT benennen (cryptography 49.0.0)
"""List the SCTs embedded in a certificate and name their logs from Chrome's CT log list."""
import base64
import json
import sys

from cryptography import x509

log_list = json.load(open(sys.argv[1]))
logs = {}
for operator in log_list["operators"]:
    for log in operator["logs"] + operator.get("tiled_logs", []):
        logs[base64.b64decode(log["log_id"])] = (operator["name"], log["description"])

cert = x509.load_pem_x509_certificate(open(sys.argv[2], "rb").read())
scts = cert.extensions.get_extension_for_class(x509.PrecertificateSignedCertificateTimestamps).value
for sct in scts:
    operator, name = logs.get(sct.log_id, ("unknown operator", "unknown log"))
    print(f"{sct.timestamp:%Y-%m-%d %H:%M:%S} UTC  {operator}: {name}  ({sct.entry_type.name})")
python3 scts.py log_list.json letsencrypt.org-1.pem; danach github.com-1.pem
2026-09-04 15:33:02 UTC  Google: Google Xenon2026h2  (PRE_CERTIFICATE)
2026-09-04 15:33:02 UTC  Geomys: Geomys Tuscolo2026h2  (PRE_CERTIFICATE)
2026-09-01 00:10:32 UTC  Google: Google Argon2026h2  (PRE_CERTIFICATE)
2026-09-01 00:10:31 UTC  Sectigo: Sectigo Tiger2026h2  (PRE_CERTIFICATE)

Die Log-Liste wurde am selben Tag von https://www.gstatic.com/ct/log_list/v3/log_list.json heruntergeladen. Jedes Zertifikat hat zwei SCTs von zwei verschiedenen Betreibern; das verlangt die CT-Richtlinie von Chrome für ein Zertifikat mit höchstens 180 Tagen Gültigkeit (für längere drei). Die Zeile Extensions: 00:00:05:00:24:DF:DB:0C am Tuscolo-SCT ist die Erweiterung leaf_index, die Logs hinzufügen müssen, wenn sie die Static CT API implementieren: Typ 0, Länge 5 und ein 40-Bit-Index, hier Eintrag 618.650.380 dieses Logs. Wegen der SCTs kann jeder alle Zertifikate durchsuchen, die für die eigene Domain ausgestellt wurden, und ein falsch ausgestelltes Zertifikat kann nicht geheim bleiben. Der SCT-Decoder dekodiert sie ohne Befehlszeile.

Häufige Fehler

  • Ein Zertifikat mit dem Namen nur im CN. Browser melden NET::ERR_CERT_COMMON_NAME_INVALID, Java meldet No subject alternative names present. Jeder Name, auch der im CN, gehört in den SAN. Das passiert am häufigsten bei internen CAs und bei Einzeilern mit openssl req, die nur -subj setzen.
  • Fehlendes Zwischenzertifikat. Funktioniert dank AIA-Chasing in Browsern und in den Plattform-Verifizierern von Windows und macOS, schlägt in OpenSSL-basierten Clients, in Go unter Linux und in Java fehl. Sende die vollständige Kette (Leaf-Zertifikat zuerst, Root-Zertifikat optional).
  • Sich auf clientAuth in einem öffentlichen Zertifikat verlassen. Es verschwindet aus den öffentlichen TLS-Hierarchien; Partnerintegrationen, die auf „ein beliebiges öffentliches Zertifikat mit clientAuth“ festgelegt wurden, brauchen eine private CA.
  • Ein CA-Zertifikat mit CA:TRUE, aber ohne keyCertSign oder nicht als kritisch markiert. Strikte Verifizierer (Python 3.13+, Go bei einigen Feldern) lehnen es ab; bei Go lautet die Meldung parent certificate cannot sign this kind of certificate.
  • Den SKI als Fingerabdruck behandeln. Er enthält, was auch immer die CA hineingeschrieben hat. Um ein Zertifikat zu identifizieren, bilde den Hash über das gesamte DER (openssl x509 -fingerprint -sha256); um einen Schlüssel zu identifizieren, den Hash über den SPKI.
  • Die Gültigkeit in Ortszeit lesen. notBefore und notAfter sind in UTC angegeben. Ein Server, dessen Uhr ein paar Stunden nachgeht, lehnt ein frisch ausgestelltes Zertifikat als noch nicht gültig ab.

Quellen