Blog Die Kurve kriegen -- Hacking the JVM for Enhanced Crypto

Die Kurve kriegen -- Hacking the JVM for Enhanced Crypto

Die Kurve kriegen -- Hacking the JVM for Enhanced Crypto

Bei einem staatlich getriebenen Projekt wie der Einf├╝hrung der elektronischen Gesundheitskarte steht die IT-Sicherheit an oberster Stelle. Dass aber die Anforderungen des Auftraggebers und der Zulassungsstelle ├╝ber das hinausgehen, was die von uns gew├Ąhlte Plattform f├╝r unser embedded device in der Telematik-Infrastruktur von Haus aus liefern kann, ruft bei uns Entwicklern und Software-Ingenieuren gemischte Gef├╝hle hervor: Der Kitzel, etwas wirklich Neues zu schaffen, aber auch die Ahnung, dass man sich auf unbekanntem Gebiet ziemlich verirren kann.

So auch bei n-design, als die neuen Spezifikationen des Auftraggebers vorschrieben, dass TLS mit ECDHE Cipher-Suiten umgesetzt werden muss. ECDHE steht f├╝r die Schl├╝sselaushandlung nach Diffie-Hellman mit Verfahren ├╝ber elliptischen Kurven. Grunds├Ątzlich ist das kein Problem, da Java schon seit einigen Jahren in diesem Bereich auch mit elliptischen Kurven umgehen kann. Au├čerdem ist es sehr zu begr├╝├čen, dass diese modernen Verfahren Aufnahme in die Spezifikation finden. Sie bieten bei vergleichbarem Rechenaufwand ein deutlich h├Âheres Sicherheitsniveau als die klassischen RSA-basierten Verfahren. Das ist f├╝r die Entwicklung eines embedded Ger├Ąts auf der Basis eines Mobilprozessors ein Segen, da die zuk├╝nftig notwendigen Schl├╝ssell├Ąngen mit der im Projekt gegebenen Hardware nicht gut zu berechnen w├Ąren.


Schwierig wurde es allerdings, als die zu verwendenden Kurven spezifiziert wurden: Nicht nur die allgegenw├Ąrtigen Kurven P256 und P384 des amerikanischen Standardisierungsinstituts NIST sollten unterst├╝tzt werden, sondern auch die Kurven Brainpool256, Brainpool384 und Brainpool512.

Letztere entstanden aus einer Initiative des ECC Brainpool, einem Zusammenschluss deutscher Unternehmen, Bildungseinrichtungen und Beh├Ârden. Ziel dieser Gruppe ist es, elliptische Kurven zu definieren, die nicht auf spezielle Algorithmen hin ausgerichtet sind, sondern die sich aus "nat├╝rlichen" Quellen wie Pi oder der Euler'schen Zahl e ableiten, und so zu besserer ├ťberpr├╝fbarkeit und Unabh├Ąngigkeit von amerikanischen Organisationen f├╝hren sollen.

Wir sind bei unserer Entwicklung auf die Java SE Plattform in der Inkarnation von OpenJDK festgelegt. Diese Plattform kennt zwar grunds├Ątzlich die Brainpool-Kurven, aber nicht f├╝r die Verwendung mit ECDHE, sondern lediglich f├╝r digitale Signaturen nach ECDSA. Dass sich das auf absehbare Zeit nicht ├Ąndern wird, wurde uns schnell klar: Die einzigen Feature-Requests auf der Java Security Mailing Liste fristen seit Jahren unbearbeitet ein Mauerbl├╝mchendasein.

Das stellte uns vor ein gro├čes Problem, zeigte andererseits aber auch einen L├Âsungsansatz auf, den wir letztendlich verfolgt haben.

Die Arbeitshypothese war, dass wir im Quellcode des OpenJDK an allen Stellen, die f├╝r ECDHE verantwortlich sind und die NIST-Kurven verwenden, zus├Ątzlich noch die drei fehlenden Brainpool-Kurven der L├Ąngen 256, 384 und 512 Bit aufnehmen w├╝rden. Wenn die Algorithmen zur Berechnung von Punkten auf den Kurven identisch sind zu denen f├╝r die NIST-Kurven, m├╝sste das klappen. Als Verifikationswerkzeuge sollten uns OpenSSL und Pari/GP dienen. OpenSSL ist das Schweizer Taschenmesser f├╝r kryptographische Verfahren, Pari/GP ist ein Algebra-Werkzeug, das an der Universit├Ąt Bordeaux entwickelt wird. Mit dieser doppelten Verifikation soll sicher gestellt werden, dass die von unserem modifizierten OpenJDK berechneten Punkte tats├Ąchlich auf der angegebenen Kurve liegen.

Die Ern├╝chterung kam recht schnell, als wir feststellten, dass nur der geringste Teil der beteiligten Codestellen im Java-Teil des OpenJDK zu finden ist. Der weitaus gr├Â├čere ÔÇô und mathematisch komplexere ÔÇô Teil liegt stattdessen im nativen Teil des Systems, das in C und C++ implementiert ist.

Wir sind bei n-design zwar sehr vielseitig aufgestellt, aber C und C++? Damit haben die Beteiligten seit dem Studium nicht mehr viel zu tun gehabt. Doch in irgendeiner Mottenkiste lag noch ein Kernighan-Ritchie und nach den ersten z├Âgerlichen Gehversuchen konnten wir auch wieder mit Zeiger-Arithmetik umgehen (auch wenn wir weiterhin froh sind, dass uns das im allergr├Â├čten Teil unserer Projekte erspart bleibt...).

Problematisch blieben die Werkzeuge: W├Ąhrend man mit printf-Ausgaben kleinere Programme noch debuggen kann, ist es bei einem komplexen System wie dem OpenJDK schon schwieriger. So schwierig, dass wir schlie├člich doch noch gelernt haben, wie der GNU Debugger in Eclipse einzubinden ist. Im Endeffekt konnten wir in einem Projekt mit zwei Programmiersprachen fast genauso effizient entwickeln wie in Java. Die gew├Ąhlten Werkzeuge zur Verifikation der Ergebnisse haben gl├╝cklicherweise sofort funktioniert: OpenSSL konnte sich mit einem TLS-Server, der unter unserem JDK lief, verbinden. Pari/GP best├Ątigte, dass die berechneten Punkt tats├Ąchlich auf der Kurve liegen.

Zu guter letzt hat sich die Arbeitshypothese bewahrheitet. Es war zwar mehr zu tun, als nur in einigen Java-Klassen Erg├Ąnzungen vorzunehmen; doch tats├Ąchlich k├Ânnen wir nun einen Haken hinter die Anforderung setzen, TLS/ECDHE mit Brainpool Kurven zu implementieren. Und manchmal hat man auch als erfahrener Softwareentwickler das Gef├╝hl, etwas wirklich Neues geschaffen zu haben.