PCP Vorstellung

Mittlerweile bin ich mit meinem Projekt Pretty Curved Privacy recht weit vorangekommen, daher dachte ich wird es an der Zeit, das hier mal ausführlicher vorzustellen.

Angefangen hat das alles, als ich - im Zuge der NSA Affäre nach Alternativen suchend - auf Curve25519 gestossen bin. Kryptographie mit eliptischen Kurven ist überaus faszinierend. Das gibt es schon länger, auch OpenSSL bietet entsprechende Algorithmen an, allerdings sind das alles NIST Standards. Und da wir mittlerweile wissen, dass das NIST von der NSA kompormittiert worden ist, muss etwas anderes her. Jedenfalls wenn man paranoid ist so wie ich. Curve25519 ist so etwas. Entwickelt von D.J.Bernstein und verfügbar in der nacl Bibliothek. Da nacl aber nicht so richtig portabel ist, gibt es eine portable Implementierung namens libsodium.

Während ich so am herumforschen war, wie man das am besten nutzen könnte, bin ich dann auf das Messaging-Framework ZeroMQ gestossen. Abseits kryptographischer Erwägungen ist ZeroMQ eine coole Sache wenn man netzwerkfähige Software schreiben will. Und es unterstützt Curve25519 über das CurveCP Protokoll. Ich spielte also mit dem Zeug so vor mich hin und irgendwann hat mich das bei CZMQ (ein Wrapper für ZeroMQ) mitgelieferte Schlüsselerzeugungstool "makecert" nur noch genervt. Es ist unflexibel und blöd. Wie es sich für einen OpenSource-Anhänger gehört, habe ich mich daher aufgerafft und etwas neues geschrieben: curve-keygen. Um das als Ersatz für makecert in das ZeroMQ Repository zu bekommen, habe ich mit den Entwicklern Kontakt aufgenommen. Die waren (und sind es noch) ohnehin gerade dabei, das Format für Curve25519 Schlüssel zu überarbeiten. Es gab dazu eine rege Diskussion auf der Mailingliste, inzwischen ist da aber Ruhe eingekehrt. Und irgendwann während dieser Diskussion habe ich angefangen, mein curve-keygen Tool neu zu schreiben. Es wurde grösser und grösser und am Ende kam Pretty Curved Privacy (PCP) heraus.

Mit PCP kann man im Grunde all die Sachen machen, die man auch mit PGP (bzw GnuPG) machen kann: Schlüssel erzeugen, verwalten, exportieren, importieren usw., Dateien ver- und entschlüsseln sowie signieren. Nur dass dabei eben keine Algorithmen zum Einsatz kommen, bei deren Entwicklung die NSA ihre Finger im Spiel hatte. Einzige Ausnahme ist SHA256 bzw SHA512, das derzeit noch für Hashes verwendet wird. Das soll aber abgelöst werden, sobald es entsprechenden Ersatz gibt.

Wie Kryptographie mit eliptischen Kurven (ECC) genau funktioniert, werde ich hier nicht erklären. Zum einen weil ich das gar nicht kann, die Mathematik ist mir viel zu heftig, das ist aus meiner Sicht mehr Magie als Mathematik. Und zum anderen wird das woanders bereits gut erklärt. Vereinfacht ist das Grundprinzip folgendes:

Bob erzeugt ein Curve25519 Schlüsselpaar bestehend aus einem öffentlichen und einem privaten Schlüssel. Alice tut das gleiche. Nun gibt Bob seinen öffentlichen Schlüssel Alice und sie tut es umgekehrt mit ihrem. Alice kann nun aus ihrem privaten Schlüssel und Bobs öffentlichen Schlüssel ein sogenanntes "shared secret" erzeugen (im Grunde eine Zahl) und Bob kann ebenfalls mit seinem privaten Schlüssel und Alice's öffentlichen Schlüssel ein "shared secret" erzeugen. Die Magie bei ECC ist nun, dass dieses "shared secret" bei beiden identisch ist! Man kann das also verwenden um Daten zu verschlüsseln, die nur der jeweilige Kommunikationspartner entschlüsseln kann. Wirklich abgefahren. Der dramatische Unterschied zum bei PGP verwendeten RSA ist, dass wenn Alice eine Nachricht für Bob verschlüsselt, dieser die nur unter Verwendung seines privaten UND Alice's öffentlichem Schlüssel entschlüsseln kann. Man kann also nicht einfach den öffentlichen Schlüssel von irgendjemand nehmen und dem dann eine Nachricht schicken. Dieser jemand muss auch einen öffentlichen Schlüssel vom Absender haben, sonst kann er damit nichts anfangen.

Dieses Szenario kann man mit PCP verwenden, es ist aber nicht die empfohlene Vorgehensweise. Obwohl ein öffentlicher Curve25519 Schlüssel zwar durchaus veröffentlicht werden kann, sollte man das lieber nicht tun. Statt dessen wird z.b. beim CurveCP Protokoll für jede Session ein dynamisches Schlüsselpaar erzeugt. Auf diese Weise kann in der Vergangenheit aufgezeichneter Traffic nicht nachträglich entschlüsselt werden, sollte einmal ein Teil der Schlüssel bekannt werden.

Bei PCP kann ich dieses Vorgehen allerdings nicht umsetzen, weil PCP offline arbeitet. Ich kann da kein Protokoll verwenden um dynamische Schlüssel auszuhandeln. Ich habe mir mit sogenannten "derived keys" abgeholfen: abgeleiteten Schlüsseln. Man sendet einem Partner also nicht den öffentlichen Schlüssel des primären Schlüsselpaars, sondern errechnet aus seinem privaten Schlüssel und einer ID einen dynamischen Schlüssel. Die ID kann die Schlüssel-ID, der Name oder die Emailadresse des Empfängers sein. Davon exportiert man den öffentlichen Schlüssel, schickt das dem Empfänger, der tut das gleiche umgekehrt und dann kann man Nachrichten austauschen. So ein abgeleiteter Schlüssel ist nur von einem bestimmten Kommunikationspartner benutzbar. Sollte er in die falschen Hände geraten, kann maximal die Kommunikation mit dieser einen Person kompromittiert werden - nicht mit allen.

Was gibts noch zu sagen? Nun, PCP ist in C geschrieben und das war eine ausgezeichnete Gelegenheit für mich, wieder da rein zu kommen. War schon eine Weile her inzwischen. Ich habe beim Entwickeln Valgrind entdeckt und lieben gelernt. Man kann gar nicht ermessen, wie sehr mit das geholfen hat, die obskursten Fehler zu finden. Ich habe ausserdem eine Unmenge an Unittests, mit denen ich sämtliche Funktionen prüfen kann. Insbesondere bei Änderungen ist das ungemein hilfreich. Das Framework dazu habe ich in Perl selber geschrieben, basierend auf dem Perlmodul Test::More, weil ich nichts passendes gefunden habe, mit dem man Unittests für command-line Tools schreiben kann. Die Unittests befinden sich im Verzeichnis tests/ im Source.

Einer der drastischsten Fehler, den ich damit gefunden hatte, war der "22-Key-Bug": neben den Unittests gibt es auch einen Stresstest, der eine grosse Menge Schlüssel verarbeitet. Das ging gut bis zum 22ten Schlüssel und dann ist PCP mit einem Segmentation Fault abgestürzt. Da hab ich vielleicht gewühlt, bis ich dem Bug auf die Schliche gekommen bin (es war ein double free, warum auch immer der erst ab dem 23ten Schlüssel anfing habe ich nie herausgefunden). Ohne Valgrind und die Unittests wäre dieser Bug noch immer im Code und ich hätte keine Ahnung davon.

Zum Schluss sei auf die Webseite von PCP hier auf dem Server verwiesen: Pretty Curved Privacy. Dort wird eigentlich alles erklärt (wie üblich auf englisch). Es gibt dort auch die aktuelle Unix Manpage pcp1(1). Den Sourcecode gibt es bei Github. Ich habe es erfolgreich unter FreeBSD, Linux (ein älteres Debian) und unter Windows 7 mit Cygwin compilieren können. Einzige Abhängigkeit ist wie erwähnt libsodium. Es gibt einen ASCII-Cast (eine Art Terminal Video), in dem ich die Verwendung demonstriere: ASCII-Cast PCP.

Zu erwähnen wäre noch, dass es sich trotz allen Aufwands, den ich bereits hineingesteckt habe, um experimentelle Software handelt, die man besser nicht für ernstzunehmende produktive Zwecke einsetzen sollte. Die Version ist auch noch unter 1 (aktuell: 0.1.3), daher können sich jederzeit Schlüssel- oder Datenbankformate ändern. Trotz allem würde ich mich natürlich über jede Art Feedback freuen :)

 

Update 2013-11-12:

Telekom kooperiert mit RSA. Mehr als die Überschrift braucht es nicht.

Update 2013-11-11:

Haha: Die IETF vertraut dem NIST auch nicht mehr.

#source

↷ 09.11.2013