Validierung elektronischer Zertifikate

vorhergehende Artikel in: Java Linux Security Python
23.01.2024

Neulich wurde ich auf eine Frage aufmerksam, die ich - sensibilisiert durch die hohe Anzahl von Vorträgen zum Thema "Validierung von Zertifikaten" auf der letzten DefCon - selber und näher untersuchen wollte: Werden elektronische Zertifikate programmiersprachen- und frameworkübergreifend identisch validiert oder existieren hier Unterschiede?

Das erste Szenario ist schnell umschrieben: Ein selbstsigniertes Zertifikat wird beim Aufbau einer TLS-Verbindung vom Server beim Client vorgezeigt. Dieser hat betreffendes Zertifikat zu seinem Truststore hinzugefügt. Die Gültigkeitsdauer des Zertifikats ist abgelaufen. Kommt die Verbindung zustande?

Wer sich den entsprechenden Abschnitt in RFC 5820 genau durchliest wird feststellen, dass es mit ein wenig geistiger Flexibilität so ist, dass man die Balidierungsvorschrift hier auf zwei verschiedene Arten auslegen kann: Das Zertifikat ist vertrauenswürdig, also muss es nicht hinsichtlich der Laufzeit validiert werden. Gleichzeitig ist es aber das letzte in der Kette und muss daher bezüglich der Laufzeit validiert werden.

Hmm - wie ist es richtig? Keiner weiß es. Da es sich hier um sicherheitsrelevante Dinge handelt, würde ich sagen, dass man bei mehreren Alternativen immer die stringenteste wählen sollte - damit würde in dem geschilderten Fall also keine Verbindung zustande kommen.

Probieren wir es in der Praxis aus, zeigt sich, dass sich in Java problemlos ein javax.net.ssl.SSLSocket öffnen lässt und mit dem Server kommuniziert werden kann. Das ändert sich erst, wenn man das Zertifikat mittels eines java.security.cert.CertPathValidator in der Geschmacksrichtung PKIX gesondert validiert.

OpenSSL hingegen und übrigens auch Python lehnen die Verbindung zu einem Server mit einem als vertrauenswürdig markierten, selbstsignierten und abgelaufenen Zertifikat jedoch standardmäßig ab.

Ein schönes Beispiel dafür, dass Validierung für elektronische Zertifikate kein Selbstläufer ist und auch nicht der Programmiersprache/ dem Framework überlassen bleiben sollte - man sollte zumindest selbst über alle Use Cases nachdenken und Tests dafür schreiben - und diese dann auch durchführen!

Ich bin übrigens nicht der Erste, der sich über das Verhalten von Java an der Stelle wundert - IBM hatte sogar mal - vielleicht ist das auch immer noch so - eine kommerzielle Java Laufzeitumgebung im Angebot, die genau an dieser Stelle vom offiziellen Java abwich und ebenfalls standardmäßig im geschilderten Szenario keine Verbindung zuließ.

Das zweite Szenario ist noch einfacher: Schwache Schlüssel. Ich habe aus diesem Projekt heraus ein Repository aufgesetzt, in dem eine Skriptsammlung alle möglichen Variationen von Zertifikaten aus einer nicht-trivialen Public Key Infrastructure (PKI) heraus erzeugt. Und hier zeigt sich ein zweiter Aspekt, bei dem sich verschieden Frameworks / Programiersprachen nicht einig sind: Eines der erzeugten Zertifikate wurde für ein Schlüsselpaar mit Schlüssellänge 1024 Bit erstellt. Nutzt man diese digitale Identität für einen TLS Server und verbindet sich mit Java (Version 17), so ist das Problemlos möglich - auch mit Anwendung des oben vorgestellten java.security.cert.CertPathValidator ändert sich daran nichts.

Python 3 in der Version 3.10.12 jedoch lehnt die Verbindung ab - mit der Meldung:

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: EE certificate key too weak (_ssl.c:1007)

Auch hieran zeigt sich, dass man seine Use Cases kennen und entsprechende automatisierte Tests dafür haben sollte um solche Probleme frühzeitig zu erkennen und korrekt auf Irregularitäten in den Zertifikaten eingehen zu können.

Artikel, die hierher verlinken

Minimierung von Angriffsoberflächen in Java

09.03.2024

Ich habe in einem früheren Artikel darauf hingewiesen, dass Java (17) und Python (3.10) sich bei der Validierung von x509-Zertifikaten ein wenig unterscheiden. Einer der Unterschiede ist die Schwelle, ab der Schlüssel wegen zu geringer Länge als unsicher bewertet und die damit verbundenen Zertifikate abgelehnt werden.

Wie man *nicht* zum Thema auf der DefCon wird...

03.02.2024

Ich habe auch vergangenes Jahr wieder einen Vortrag zum 37c3 eingereicht, der aber leider nicht angenommen wurde...

Alle Artikel rss Wochenübersicht Monatsübersicht Github Repositories Gitlab Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Aviator + Websockets

    15.06.2019

    Nachdem ich in den letzten Wochen und Monaten meine Zeit und Energie in die sQLshell gesteckt habe - was sowohl Bugfixing als auch neue Features betraf - habe ich nun endlich die Zeit gefunden, ein bereits lange überfälliges Feature an dWb+ und speziell am aviator zu implementieren.

    Weiterlesen...

Neueste Artikel

  • Neue Version plantumlinterfaceproxy napkin look

    Es gibt eine neue Version des Projektes plantumlinterfaceproxy - Codename napkin look.

    Weiterlesen...
  • Apache HTTPCore5 funktioniert nicht mit Docker

    Ich habe neulich drei Stunden meines Lebens verschwendet weil ich unbedingt die neueste Version der HTTPCore5 Library von Apache einsetzen wollte.

    Weiterlesen...
  • Entwurfsmodus für beliebige SVG Graphiken

    Nachdem ich in der Vergangenheit immer wieder Weiterentwicklungen der Idee vorgestellt habe, Graphiken mit dem Computer so zu ezeugen dass sie eine gewisse "handgemachte" Anmutung haben, habe ich nunmehr die durchschlagende Idee gehabt:

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muß damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.