Zum Inhalt springen
ecdsa.com
← Alle Artikel

Certificate Transparency für Entwickler: SCTs und Alerts

Jedes öffentlich vertrauenswürdige TLS-Zertifikat wird in Append-only-Logs veröffentlicht, bevor Browser es akzeptieren. Dadurch werden fehlerhaft ausgestellte Zertifikate sichtbar, und dein eigener Bestand an Zertifikaten wird durchsuchbar. Hier erfährst du, wie die Teile zusammenspielen, was Browser verlangen und wie du deine Domains überwachst.

Kurz gesagt. Certificate Transparency (CT, RFC 6962) verpflichtet CAs, jedes öffentlich vertrauenswürdige TLS-Zertifikat bei öffentlichen Append-only-Logs einzureichen. Jedes Log gibt den SCT zurück, ein signiertes Versprechen, das Zertifikat aufzunehmen, und die CA bettet die SCTs in das Zertifikat ein. Chrome, Safari und Firefox lehnen öffentlich vertrauenswürdige Zertifikate ab, die nicht genug SCTs von genug unabhängigen Logs mitbringen. Für dich bedeutet das zweierlei. Jeder kann über Cert Spotter, crt.sh oder einen eigenen Monitor jedes Zertifikat sehen, das für deine Domains ausgestellt wurde. Und du solltest diese Logs im Blick behalten, denn ein Zertifikat, das du nicht beantragt hast, ist das früheste Anzeichen für eine DNS-Übernahme, ein kompromittiertes Konto oder eine CA, die sich nicht an die Regeln hält.

So funktioniert CT

Ein CT-Log ist ein Merkle-Baum, dieselbe Append-only-Hash-Struktur, die auch Git und Bitcoin verwenden. Jeder kann das Log herunterladen, prüfen, dass Einträge nie entfernt oder verändert werden, und einen kurzen Nachweis abrufen, dass ein bestimmtes Zertifikat darin enthalten ist. Die Ausstellung mit CT läuft so ab:

  1. Die CA erstellt ein Präzertifikat: den Inhalt des endgültigen Zertifikats plus eine kritische „Poison“-Erweiterung (OID 1.3.6.1.4.1.11129.2.4.3), damit es sich nicht als echtes Zertifikat verwenden lässt.
  2. Die CA reicht das Präzertifikat bei mehreren Logs ein. Jedes Log gibt einen Signed Certificate Timestamp (SCT) zurück: eine Signatur über den Eintrag und einen Zeitstempel, die zusichern, dass der Eintrag innerhalb der Frist aufgenommen wird, die das Log als Maximum Merge Delay (MMD) festlegt.
  3. Die CA stellt das endgültige Zertifikat aus und bettet die SCTs in eine X.509-Erweiterung ein (OID 1.3.6.1.4.1.11129.2.4.2).
  4. Browser prüfen die SCT-Signaturen anhand ihrer Liste vertrauenswürdiger Logs und gleichen die Anzahl mit ihrer Richtlinie ab.
  5. Monitore lesen die Logs und melden Zertifikate für die Namen, die sie beobachten. Auditoren prüfen, ob die Logs konsistent bleiben und ihre Versprechen halten.

Präzertifikat und endgültiges Zertifikat werden in den meisten Fällen beide in die Logs eingetragen. Deshalb zeigen Such-Tools jedes Zertifikat oft doppelt an.

Die SCTs in einem echten Zertifikat

openssl x509 -text dekodiert die eingebetteten SCTs. Das hier ist das Zertifikat, das letsencrypt.org am 20. Oktober 2026 ausgeliefert hat:

openssl x509 -noout -text (OpenSSL 3.5.7, gekürzt)
subject=CN=letsencrypt.org
issuer=C=US, O=Let's Encrypt, CN=YE2
notBefore=Sep  4 14:34:32 2026 GMT
notAfter=Dec  3 14:34:31 2026 GMT
            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:...

Die Log-ID ist der SHA-256-Hash des öffentlichen Schlüssels des Logs. Ein Abgleich beider IDs mit der Log-Liste von Chrome (log_list.json, Stand 19. Oktober 2026) ergibt:

Log-ID (base64)LogBetreiberTypStatus
2AlVO5RPev/IFhlvlE+Fq7D4/F6HVSYPFdEucrtFSxQ=Xenon2026h2GoogleRFC 6962, MMD 24 hnutzbar
Rq+GPTs+5Z+ld96oJF02sNntIqIj9GF3QSKUUu6VUF8=Tuscolo2026h2Geomysstatic-ct-api, MMD 60 snutzbar

Zwei Logs von zwei verschiedenen Betreibern – das Minimum für ein 90-Tage-Zertifikat. Die Erweiterung des zweiten SCT ist kein Rauschen. Logs nach der static-ct-api schreiben die Position des Eintrags im Log in den SCT: Erweiterungstyp 0 (leaf_index), Länge 5 und ein 40-Bit-Index, hier 618.650.380. Ein Monitor kann diesen Eintrag direkt abrufen, statt nach ihm zu suchen.

Der SCT-Decoder übernimmt das Nachschlagen für dich. Er zeigt den Namen jedes Logs, seinen Status in den Listen von Chrome und Apple und ob die SCTs zusammen die Richtlinie jedes Browsers erfüllen. Der Zertifikats-Decoder zeigt die SCT-Erweiterung zusammen mit dem Rest des Zertifikats.

SCTs können auf drei Wegen zum Browser gelangen:

  • Eingebettet im Zertifikat, wie oben. So machen es fast alle CAs, und von dir ist dafür nichts nötig.
  • In der TLS-Erweiterung signed_certificate_timestamp. Der Server sendet SCTs, die er selbst beschafft hat. Nur wenige Server unterstützen das.
  • Per Stapling in einer OCSP-Antwort. Chrome akzeptierte solche SCTs nur „in Versionen vor Version 148“, und da Let's Encrypt und andere OCSP einstellen, verliert dieser Weg an Bedeutung (siehe OCSP und CRL im Jahr 2026).

Was Browser verlangen

Alle drei großen Browser-Engines setzen CT für Zertifikate von CAs aus ihren öffentlichen Root-Programmen durch.

ChromeApple (Safari, iOS, macOS)Firefox
Eingebettete SCTs, Laufzeit ≤ 180 Tage2 aus verschiedenen Logs22 aus verschiedenen Logs
Eingebettete SCTs, längere Laufzeit3 aus verschiedenen Logs3 (181–398 Tage)3 aus verschiedenen Logs
Vielfalt der BetreiberMindestens 2 verschiedene Log-BetreiberPro Betreiber zählen höchstens 1 (≤ 180 Tage) oder 2 (längere Laufzeit) SCTsMindestens 2 verschiedene Log-Betreiber
Weitere BedingungenMindestens ein eingebetteter SCT von einem Log, das aktuell den Status Qualified, Usable oder ReadOnly hatMindestens ein eingebetteter SCT von einem aktuell zugelassenen Log. Mindestens ein SCT von einem Log nach RFC 6962Mindestens ein SCT von einem aktuell zulässigen Log. Die Log-Liste ist die von Chromium
SCTs per TLS oder OCSP2 von aktuell vertrauenswürdigen Logs, 2 Betreiber. OCSP nur vor Chrome 1482 von aktuell zugelassenen Logs, einer davon per TLS oder OCSP übermittelt2 von zulässigen Logs, 2 Betreiber
Fehler bei NichterfüllungNET::ERR_CERTIFICATE_TRANSPARENCY_REQUIREDVerbindung schlägt fehlMOZILLA_PKIX_ERROR_INSUFFICIENT_CERTIFICATE_TRANSPARENCY

Quellen: die CT-Richtlinie von Chrome, Apples CT-Richtlinie (April 2025) und Mozillas CT-Seite. Laut MDN setzt Firefox CT auf dem Desktop seit Version 135 (Februar 2025) durch und unter Android seit Version 145 (November 2025). Die Einstellung security.pki.certificate_transparency.mode zeigt den Modus: 2 bedeutet, dass CT durchgesetzt wird.

Zwei praktische Folgen:

  • Browser setzen CT nicht mehr durch, wenn ihre Log-Liste zu alt ist. Chrome setzt CT nur durch, solange seine neueste Log-Liste jünger als 70 Tage ist, und die Liste von Firefox läuft nach 10 Wochen ab. Ein Rechner, der seit Monaten keine Updates bekommen hat, setzt CT überhaupt nicht durch. Teste CT-Fehler also nicht auf so einem Rechner.
  • Private CAs sind ausgenommen. Laut den Hinweisen für Unternehmen von Chrome gilt CT „nur für CAs, die öffentlich vertrauenswürdig sind“. Zertifikate unter einem Root-Zertifikat, das du selbst installiert hast, brauchen keine SCTs, und Logs nehmen sie ohnehin nicht an.

Die Logs selbst

Die Log-Liste von Chrome vom 19. Oktober 2026 zählt 21 nutzbare Logs nach RFC 6962, dazu 2 schreibgeschützte und 3 stillgelegte. Außerdem führt sie 22 nutzbare und 37 qualifizierte static-ct-api-Logs. Elf Betreiber haben Logs, die nutzbar oder qualifiziert sind: Cloudflare, DigiCert, Geomys, GoDaddy, Google, HARICA, IPng Networks, Let's Encrypt, Microsec, Sectigo und TrustAsia. Logs sind zeitlich in Shards aufgeteilt. Ein Log namens 2026h2 nimmt nur Zertifikate an, die in der zweiten Jahreshälfte 2026 ablaufen. So bleibt die Größe jedes Logs begrenzt, und das Log kann stillgelegt werden, sobald seine Zertifikate abgelaufen sind.

Beide Arten von Logs nehmen Einreichungen über dieselben Endpunkte aus RFC 6962 an (add-chain, add-pre-chain). Der Unterschied liegt darin, wie Monitore sie lesen. Ein Log nach RFC 6962 beantwortet dynamische API-Aufrufe:

GET https://ct.googleapis.com/logs/eu1/xenon2026h2/ct/v1/get-sth (20. Oktober 2026)
{"tree_size":2980148930,"timestamp":1792499093002,"sha256_root_hash":"wr3F5apMl2E7wQHqbAA1yKsqaZbAzBXTT8WTAeRAy8M=","tree_head_signature":"BAMARzBFAiEAsC3Pr7fsPwy0vchrMDIXka7HxrZANu5tcXclDCUqqSYCIGJ64SaIT0tjM5hCGfycNGPfu6FP8q8RvW14Q4SoyvVU"}

Das sind knapp drei Milliarden Einträge in einem einzigen Halbjahres-Shard. Ein static-ct-api-Log (auch „Tiled Log“ genannt) veröffentlicht seinen signierten Tree Head als Checkpoint in einfachem Textformat und seine Einträge als unveränderliche Kacheln (Tiles) mit je 256 Einträgen, die CDNs cachen können:

GET https://tuscolo2026h2.skylight.geomys.org/checkpoint (20. Oktober 2026, Signaturen gekürzt)
tuscolo2026h2.sunlight.geomys.org
1007870339
aRhh7dPjYarH0itUM1LD+XJw7CW41z1+9tSnf3AizuY=

— tuscolo2026h2.sunlight.geomys.org W+DWDWi4dqCfFx8da0IS4+jwHKVL6ETEHGQCHn5y8rKflUhLRtLHQ3c6...
— grease.invalid Aui1jDc8Y7Uve7seHd/Pg1p+wHSUmw0+MTNyEKEAAbHaE5bY3Gi/MUZ3zBuk+NxUyhJL...
— tuscolo2026h2.sunlight.geomys.org 7BiSLwAAAaFZRnbMBAMARzBFAiA++3wWdtsK2H8l3IxZh6H/OQml...

Die ersten Zeilen sind der Origin, die Baumgröße und der Root-Hash. Die Zeilen, die mit „—“ beginnen, sind Signaturen. Beachte, dass sich die URL für das Monitoring (skylight) von der URL für Einreichungen (sunlight) unterscheidet. Beide stehen in der Log-Liste.

Zwei öffentliche Suchdienste decken praktisch alle Logs ab.

Cert Spotter API (SSLMate). Der Issuances-Endpunkt listet die nicht abgelaufenen Zertifikate einer Domain auf. Ohne API-Schlüssel funktioniert er für eine begrenzte Zahl von Abfragen pro Stunde. Für den Produktiveinsatz bittet SSLMate darum, dass du dich für einen API-Schlüssel registrierst. Hier sind die Zertifikate für ecdsa.com:

Cert Spotter: nicht abgelaufene Zertifikate einer Domain und ihrer Subdomains
curl -s "https://api.certspotter.com/v1/issuances?domain=ecdsa.com&include_subdomains=true&expand=dns_names&expand=issuer"
Erster Datensatz der Antwort (20. Oktober 2026)
{
  "id": "16609031524",
  "tbs_sha256": "8c6f1f0bef5434da2012d5f29eab13f00bcec659f17832c07872ff600f61ecf5",
  "cert_sha256": "1396447e3454a081fe4e48dc1d5de18b7e3cf857ec1d7ff3c987d091c9024b04",
  "dns_names": [
    "ecdsa.com"
  ],
  "pubkey_sha256": "9a1fa381dad4630b83cf3a1a1a7a3da7f04577db8a41933dd9bac49dabfa8c29",
  "issuer": {
    "friendly_name": "Let's Encrypt",
    "pubkey_sha256": "2e8307068b6db620e4a39d068b5dee5d6ef5788cbb2c0b6d23ead84fcc17178c",
    "name": "C=US, O=Let's Encrypt, CN=YR1"
  },
  "not_before": "2026-08-19T14:52:58Z",
  "not_after": "2026-11-17T14:52:57Z",
  "revoked": false
}

Zusammengefasst enthielt die Antwort fünf Ausstellungen:

Alle fünf Ausstellungen, eine pro Zeile
16609031524 2026-08-19 2026-11-17 Let's Encrypt ecdsa.com
16609045002 2026-08-19 2026-11-17 Let's Encrypt ecdsa.com,www.ecdsa.com
17525925247 2026-10-01 2026-12-30 Let's Encrypt *.ecdsa.com,ecdsa.com
17875915585 2026-10-19 2027-01-17 Let's Encrypt ecdsa.com,www.ecdsa.com
17878726033 2026-10-20 2027-01-18 Let's Encrypt ecdsa.com

Die Ergebnisse kommen in der Reihenfolge, in der SSLMate sie entdeckt hat. Zum Weiterblättern übergibst du die letzte id als after=. Ein leeres Array kommt mit einem Header Retry-After, wodurch sich der Endpunkt als Polling-Feed eignet. Beachte, was das Feld pubkey_sha256 möglich macht. Ein Vergleich mit den Schlüsseln deiner Server zeigt, welche Zertifikate tatsächlich im Einsatz sind und welche zwar ausgestellt, aber nie genutzt wurden.

crt.sh (Sectigo) bietet eine Weboberfläche und eine JSON-Ausgabe (https://crt.sh/?q=example.com&output=json). Der Dienst ist kostenlos und reicht sehr weit in die Vergangenheit zurück, abgelaufene Zertifikate eingeschlossen. Er ist aber auch ein stark ausgelasteter, gemeinsam genutzter Dienst. Alle vier unserer JSON-Abfragen am 20. Oktober 2026 lieferten 502 Bad Gateway. Nutze ihn als bequeme Ergänzung, nicht als Abhängigkeit deines Monitorings.

Das Tool CT-Historie zeigt die Zertifikate einer Domain im zeitlichen Verlauf, jeweils mit Aussteller, Gültigkeit und Namen.

Monitoring für deine Domains

Die Suche beantwortet die Frage „Was gibt es?“. Monitoring beantwortet „Was ist neu?“ und benachrichtigt dich innerhalb von Minuten oder Stunden nach der Ausstellung. Die Optionen:

  • Ein gehosteter Monitor. Der gehostete Dienst Cert Spotter von SSLMate und die Dashboards mehrerer CAs schicken E-Mails oder Webhooks, wenn für deine Domains neue Zertifikate auftauchen.
  • Das Open-Source-Tool certspotter (v0.25.0, September 2026) liest die Logs selbst. Du trägst Namen in ~/.certspotter/watchlist ein (ein führender Punkt erfasst alle Subdomains, z. B. .example.com), und bei jedem Treffer schickt es dir eine E-Mail oder führt Skripte aus ~/.certspotter/hooks.d aus. Seit v0.24 bringt es außerdem certspotter-authorize mit, das erwartete Zertifikate markiert, sodass nur die unerwarteten einen Alert auslösen.
  • Die Such-API als Feed. Frag den Issuances-Endpunkt von Cert Spotter regelmäßig mit after= ab und vergleiche jedes neue Zertifikat mit dem, was deine Automatisierung ausgestellt hat.

Wofür du Alerts einrichten solltest:

  1. Ein Aussteller, den du nicht nutzt. Gleiche ihn mit deinen CAA-Einträgen ab. Ein Zertifikat von einer CA, die deine CAA-Einträge nicht zulassen, ist ein CA-Vorfall und muss der CA gemeldet werden.
  2. Namen, die du nicht zuordnen kannst, besonders vergessene Subdomains. Ein Zertifikat für old-campaign.example.com kann bedeuten, dass jemand einen verwaisten DNS-Eintrag übernommen hat.
  3. Ein öffentlicher Schlüssel, den du nicht erzeugt hast, für einen Namen, den deine Automatisierung verwaltet.
  4. Wildcard-Zertifikate, wenn deine Richtlinie keine vorsieht.

Mit 47-Tage-Zertifikaten werden legitime Ausstellungen häufig. Ohne certspotter-authorize oder einen Abgleich mit den Aufzeichnungen deines ACME-Clients sorgt die Flut von Alerts dafür, dass du genau das eine Zertifikat ignorierst, auf das es ankommt.

CT und private Namen

Alles in einem öffentlich vertrauenswürdigen Zertifikat wird veröffentlicht: jeder Name in der SAN-Liste, für immer. Interne Hostnamen wie jenkins.corp.example.com oder staging-payments.example.com werden öffentlich, sobald du ein öffentliches Zertifikat für sie beziehst, und jeder, der die Logs liest, sieht sie, auch wer nach Angriffszielen scannt. Die Möglichkeiten laut den Hinweisen von Chrome für Unternehmen und gängiger Praxis:

  • Nutze eine private CA für interne Namen. CT gilt dann nicht, und nichts wird veröffentlicht.
  • Nutze ein Wildcard-Zertifikat (*.corp.example.com), wenn sich ein öffentliches Zertifikat nicht vermeiden lässt. Es verrät die Zone, aber nicht jeden einzelnen Host.
  • Verlass dich nicht darauf, eine öffentliche CA zu bitten, das Zertifikat nicht in Logs einzutragen. Es würde dann in jedem Browser scheitern, der CT durchsetzt.

Häufige Fehler

  • Annehmen, ein SCT beweise die Aufnahme ins Log. Ein SCT ist ein Versprechen, den Eintrag innerhalb der MMD aufzunehmen. Auditoren und Monitore prüfen, ob die Logs es einhalten.
  • Duplikate mitzählen. Einträge für Präzertifikat und Zertifikat derselben Ausstellung erscheinen in den meisten Such-Tools als zwei Zeilen. Beide haben denselben Aussteller und dieselbe Seriennummer, also dedupliziere anhand dieses Paars, bevor du Zertifikate zählst.
  • Widerrufsinformationen in CT erwarten. Ein widerrufenes Zertifikat bleibt für immer im Log. Der Widerruf ist ein eigenes System.
  • Die Durchsetzung mit einem alten Browser testen. Die CT-Durchsetzung schaltet sich selbst ab, wenn die Log-Liste des Browsers veraltet ist.
  • Monitoring über nur einen kostenlosen Dienst. Ausfälle von crt.sh kommen vor. Nutze eine zweite Quelle oder einen eigenen Monitor.

Quellen

Die Befehlsausgaben wurden am 20. Oktober 2026 mit OpenSSL 3.5.7 und curl 8.14.1 in node:24.22.0-trixie erzeugt.