badkeys
Unsichere kryptographische Schlüssel
Public-Key-Kryptographie
🔑 Öffentlicher Schlüssel
🔑 Privater Schlüssel
Verschlüsselung (veraltet)
Verschlüsseln mit öffentlichem Schlüssel🔑
Entschlüsseln mit privatem Schlüssel🔑
Digitale Signaturen
Signieren mit privatem Schlüssel🔑
Prüfen mit öffentlichem Schlüssel🔑
Public-Key-Verfahren
- RSA
- ECDSA, Ed25519/Ed448 (elliptische Kurven)
- ML-DSA, ML-KEM (Post-Quanten-Krypto)
Wo wird Public-Key-Kryptographie genutzt?
TLS, HTTPS, SSH, DKIM, DNSSEC, ...
Fahrkarten, E-Perso, Impfzertifikate, ...
Public-Key-Kryptographie ist nur sicher, wenn der private Schlüssel geheim ist
Sicherheitslücke in keypair / GitKraken (2021)
"There is no haveibeenpwned for public keys as far as I know"
("Es gibt soweit ich weiß kein haveibeenpwned für öffentliche Schlüssel")
user jornane on lobste.rs, 10/2021
haveibeenpwned für Public Keys?
Klingt nach einer guten Idee!
CVE-2008-0166
Debian-OpenSSL-Bug
Durch einen fehlerhaften Patch funktionierte der Zufallszahlengenerator nicht korrekt
und verwendete lediglich die Prozess-ID (PID) als Zufallsquelle
Testen, ob Schlüssel für Debian-OpenSSL-Bug verwundbar ist
(vor badkeys)
- Alte Skripte, die auf modernen Systemen nicht funktionieren
- Unvollständige Sammlungen oder Hash-Listen von betroffenen Schlüsseln
- Verwirrende, unvollständige oder falsche Informationen
Schlüsselvarianten Debian-OpenSSL-Bug
- PID (0 bis 32768)
- OpenSSL oder OpenSSH
- CPU-Architektur
- Schlüsselgröße
- Ältere oder neuere Version des betroffenen OpenSSL-Pakets
- Konfigurationsunterschiede
Alle Varianten des Debian-OpenSSL-Bugs zu erkennen ist unpraktikabel,
badkeys erkennt aber alle plausiblen Varianten
Warum redet der so viel über eine 17 Jahre alte Sicherheitslücke?
DKIM
DomainKeys Identified Mail
DKIM E-Mail header
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hboeck.de; s=key1; t=1715197611; bh=Z9fPSuWvmaUL/fgn9g0k2ORYPJe3Y3Vc5NiKvQJXc2w=; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type: Content-Transfer-Encoding; b=TNyZHQd[...]
TXT record key1._domainkey.hboeck.de
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQE[...]
Scan von DKIM-Keys
Benötigt passende DKIM-Selektoren, extrahieren aus bestehenden Mails oder gängige
Selektoren (key, dkim, ...) raten / bruteforce
DKIM Scan mit badkeys (2024)
0,24 % der gescannten DKIM-Records betroffen von Debian-OpenSSL-Bug (2024!)
Betroffene Hosts
@cisco.com, @oracle.com, @skype.net, @github.partners, @partner.crowdstrike.com,
@partners.dropbox.com, @1password.com
BIMI
Brand Indicators for Message Identification
💰💰💰
Warum waren relativ viele DKIM-Setups von einem 16 Jahre alten Bug betroffen?
2006: Debian-OpenSSL-Paket mit Bug veröffentlicht
2007: RFC 4871 (DKIM)
2008: Debian-OpenSSL-Bug wird entdeckt und gefixt
Debian OpenSSL Bug und DKIM
Mehr Infos und Vortragsvideo (MiniDebConf)
Fermat-Angriff (1643)
RSA-Schlüssel
Öffentlicher Schlüssel: N, e
Privater Schlüssel: N, e, d, p, q, dP, dQ, invQ
Faktorisierung
N = p · q
N: Modulus (öffentlich), p/q: Primzahlen (privat)
N = p · q
Aus p oder q und dem öffentlichen Schlüssel kann man den gesamten private Schlüssel berechnen
Die Sicherheit von RSA hängt davon ab, dass
Faktorisierung "schwierig" ist
N = p · q
a: Mitte zwischen p und q
b: Abstand zwischen a und p/q
N = (a + b) · (a - b)
N = (a + b) · (a - b)
N = a² - b²
b² = a² - N
b² = a² - N
Wir raten Werte von a
(Start: √N) und prüfen, ob das Resultat eine Quadratzahl ist
a = gmpy2.isqrt(n)
while not gmpy2.is_square(a**2 - n):
a += 1
bsq = a**2 - n
b = gmpy2.isqrt(bsq)
p = a + b
q = a - b
Fermat-Faktorisierung ist schnell, wenn Primzahlen nah beieinander liegen
1993 - 1996
Rechtsextreme Bombenanschläge in Österreich
(Bajuwarischen Befreiungsarmee, Franz Fuchs)
Scan von TLS-Zertifikaten mit Fermat-Faktorisierung (2022)
CVE-2022-26320
Drucker von Canon und Fujifilm (TLS-Bibliothek von Rambus)
erstellten verwundbare Zertifikate
Angenommen, wir haben zwei RSA-Keys mit einer gemeinsamen und einer unterschiedlichen Primzahl
N₁ = p₁ · q₁
N₂ = p₂ · q₁
Größter gemeinsamer Teiler
N₁ = p₁ · q₁ N₂ = p₂ · q₁
ggT(N₁, N₂) = q₁
BatchGCD
Größte gemeinsame Teiler von vielen Zahlen
Warum passiert sowas?
Die betroffenen Schlüssel wurden überwiegend auf Embedded-Geräten unter Linux erstellt
Zufallszahlengenerator des Betriebssystems
Tastatureingaben,
Festplatten-Zugriffszeiten, etc., werden genutzt, um den Zufallszahlengenerator
zu initialisieren
- Betriebssystem startet, Zufallszahlengenerator ist noch nicht sicher initialisiert
- Startskript erzeugt RSA-Schlüssel beim Booten
- Erste Primzahl wird erzeugt (unsicher, kann sich wiederholen)
- Betriebssystem sammelt weitere Zufallsdaten
- Zweite Primzahl wird erzeugt (sicher)
Nach dem Paper gab es zahlreiche Änderungen am Linux-Kernel, um derartige Szenarien zu
vermeiden
Sichere, zufällige Primzahl?
c0000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000000000000000000000000002f9
c9242492249292499249492449242492
24929249924949244924249224929249
92494924492424922492924992494924
492424922492924992494924492424e5
BSI-zertifizierte Chipkarten
ROCA
Return of Coopersmith's Attack (2017)
ROCA
Sicherheitslücke in RSA-Chips von Infineon,
Schlüssel lassen sich erkennen und (mit Aufwand) brechen
Wegen ROCA mussten in Estland
Ausweise mit verwundbaren Chips ausgetauscht werden
Auch diese Chipkarten waren BSI-zertifiziert
badkeys-Fund
Zertifikate von Yahoo mit ROCA-Keys (Ausgestellt 2021)
Public Private Keys
Öffentliche private Schlüssel
Private Schlüssel, die man auf öffentlichen Webseiten finden kann, sind nicht sicher!
beA - besonderes elektronisches Anwaltspostfach (2017)
beA
Versuch 1: Von CA signiertes Zertifikat für bealocalhost.de mit Schlüssel in der Anwendung
beA
Versuch 2: Selbstsigniertes CA-Zertifikat mit Schlüssel in der Anwendung
Jenkins Docker-Images
Hardcodierter SSH-Host-Key (CVE-2025-32754, CVE-2025-32755)
https://www.treasury.go.ke/treasury.go.ke.key
Es gibt viele Arten von öffentlichen privaten Schlüsseln
- Beispiele in Dokumentation
- Test-Keys in Softwarepaketen
- Geleakte Keys
- Vorgenerierte Keys in Firmware-Images, Containern, VM-Images
- Sicherheitslücken (Debian-OpenSSL-Bug, keypair-Bug)
- ...
CVE-2022-40684
Authentication Bypass in FortiGate-Geräten
Bereits 2022 bekannt, dass diese aktiv ausgenutzt wurde
Januar 2025
~15.000 Konfigurationsdateien von FortiGate-Geräten werden auf BreachForums
veröffentlicht
Diese Konfigurationsdateien enthalten private Schlüssel, allerdings
sind diese mit einem Passwort verschlüsselt
Das Passwort ist auch in den Konfigurationsdateien, aber ebenfalls verschlüsselt
Das Schlüssel-Passwort wiederum war mit dem Passwort "Mary had a littl" verschlüsselt
FortiGate (2025)
Private Schlüssel für ~100 nach wie vor gültige TLS-Zertifikate und
für ~300 ACME-Accounts (Let's Encrypt)
Vorfall war seit 2022 bekannt!
https://example.com/.well-known/openid-configuration
JSON Web Key Öffentlich
{
"kty": "EC",
"crv": "P-256",
"x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
"y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"
}
JSON Web Key Privat
{
"kty": "EC",
"crv": "P-256",
"x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
"y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
"d": "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE"
}
JSON Web Keys haben die Eigenschaft, dass das Format für private und
öffentiche Schlüssel quasi identisch ist
Privater Schlüssel? Öffentlicher Schlüssel?
Kann man ja mal verwechseln....
OpenID-Konfigurationen mit privaten Schlüsseln, mit Beispiel-Keys, sowie
mit 512-Bit-RSA-Schlüsseln
Technische Details zu badkeys
Verschiedene Arten von Tests
Algorithmische Erkennung (Fermat, ROCA)
Liste von bekannten, unsicheren Schlüsseln (Debian-OpenSSL-Bug, Beispiel-Keys)
Hybrid (gemeinsame Primzahlen)
Liste von unsicheren Schlüsseln
Hash des öffentlichen Schlüssels?
Möglich, aber nicht optimal.
Öffentlicher RSA-Schlüssel
N (Modulus), e (Exponent)
badkeys-Blockliste: Hash des Modulus N
Angenommen, wir haben zwei RSA Schlüssel mit identischem Modulus, aber
unterschiedlichem Exponenten
Key 1: N₁, e₁ Key 2: N₁, e₂
Wenn ein privater Schlüssel bekannt ist, lässt sich der andere effizient berechnen
Beispiel: Debian-OpenSSL-Bug
Standardmäßig nutzt OpenSSL den Exponenten e=65537, aber eine Kommandozeilenoption erlaubt
die Verwendung von e=3
Da badkeys nur den Modulus betrachtet, erkennt es derartige Keys automatisch
Elliptische Kurven
Es gibt verschiedene Möglichkeiten, öffentliche Schlüssel zu codieren
(X/Y-Wert, X-Wert und Point Compression)
badkeys betrachtet bei elliptischen Kurven nur den X-wert und kann daher Details der Codierung
ignorieren
badkeys in der Praxis
Demo Time!
badkeys installieren und vorbereiten
pip install badkeys
badkeys --update-bl-and-urls
badkeys Kommandozeile
Demo Time!
badkeys Erkennung
- Fermat-Faktorisierung
- Gemeinsame Primfaktoren
- ROCA
- Debian-OpenSSL-Bug
- keypair-Bug
- Zahlreiche öffentliche private Schlüssel
Zukunft
Ausweitung der erkannten kompromittierten Schlüssel
Regelmäßige Scans von DKIM, DNSSEC, TLS-Zertifikaten
(unterstützt von NGI0/NLnet)
Ideen? Sponsoring? Consulting?
Sprecht mich gerne an!
Fragen?