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 Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    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, muss 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 Codeberg-Repositories findet man hier.