OpenPGP (RfC 4880, Wikipedia-Eintrag) zur Verschlüsselung von E-Mails (und Dateien) gibt es schon seit 1996, aber leider hat es sich immer noch nicht so weit verbreitet, dass die Masse der Kommunikation gesichert wäre. Ein Problem bei jeglicher Verschlüsselung ist der Schlüsselaustausch und die Frage, wie sicher man diesen gestalten will. Lange war die Diskussion über den Schlüsselaustausch und die Schlüsselprüfung von dem Extrem geprägt, dass ständig und überall ein Angreifer lauern würde, der alle Schlüssel durch seinen eigenen ersetzt und alles zerstört. Dies hat die Hürde für Verschlüsselung so hoch gesetzt, dass die Mehrzahl der Nutzer abgewunken hat und einfach unverschlüsselte E-Mails schreibt – ein Beispiel dafür, dass gut gemeinter Extremismus nicht immer Gutes bewirkt.

Gretchenfrage: Wie hältst Du's mit der Sicherheit?

Bei der Form der asymmetrischen Verschlüsselung, wie sie bei PGP genutzt wird, erzeugt jeder Nutzer einen Schlüssel mit öffentlichem und privatem Anteil. Nur diese Kombination gemeinsam funktioniert. Der öffentliche Schlüsselteil kann beliebig verteilt werden, der private Teil muss streng geheim gehalten werden – womit es für Webmailer sehr schwierig, aber nicht unmöglich wird, wie web.de gezeigt hat. Alle Kombinationen mit anderen Teilen können weder gültige verschlüsselte Nachrichten erzeugen, noch können sie Nachrichten entschlüsseln. Daher ist klar, dass eine Nachricht nur von dem einen Besitzer des privaten Schlüsselteils stammen kann, wenn man sie mit dem dazugehörigen öffentlichen Schlüsselteil entschlüsseln kann und umgekehrt.

Aber öffentlich ist gar nicht so einfach, wie es sich dahinsagt. Wo veröffentlicht man den Schlüssel? Man kann ihn ja nicht dem anderen senden, denn die gesicherte Verbindung besteht ja noch nicht. Bis vor einigen Jahren ging der Weg immer über Key-Server, die viele öffentliche Schlüssel gespeichert haben. Dort kann man seinen Schlüssel hinterlegen oder nach anderen Schlüsseln suchen. Aber wer sagt, dass der Schlüssel dort wirklich der richtige für die E-Mailadresse ist? Hierfür wurde ein zweiter Weg, meist das persönliche Treffen bemüht, um einen sogenannten Fingerprint (eine Prüfsumme) des Schlüssels auszutauschen. Damit war dann sichergestellt, dass der öffentliche Schlüssel wirklich der Person gehört, die man getroffen hatte und hoffentlich kennt.

Als so richtig gut hat sich dieses Verfahren in der Praxis jedoch nicht erwiesen, dann spätestens der Aufwand eines persönlichen Treffens mit Abgleich von Fingerprints schreckt jeglichen Standardnutzer ab. Solche Sicherheitsstufen kann man optional gehen, aber für die einfache Kommunikation wäre es schon allein hilfreich, wenn irgendwie verschlüsselt würde, anstatt die Nachrichten im Klartext zu senden.

Schlüsselprüfung bei modernen Chatsystemen

Bei WhatsApp, Matrix und anderen, modernen Chatsystemen hat man genau diese Stufen eingebaut und daher passiert die grundlegende Verschlüsselung beiläufig und ist nicht wirklich spürbar. Nur durch einige spezielle Nachrichten im Verlauf fällt auf, dass die Verschlüsselung aktiv ist, und in den Kontaktdaten wird deutlich, dass es eine Verschlüsselung gibt. WhatsApp und Matrix erzeugen bei der Einrichtung des Kontos eben jenes Schlüsselpaar und kümmern sich um die Verteilung – ein Vorteil den E-Mail leider nicht hat.

Aber auch bei der Prüfung der Schlüssel sind diese Systeme laxer. Durch den Schlüsselaustausch innerhalb des Systems ist schon recht sicher, dass der Schlüssel dem wahren Eigentümer gehört und oft ist auch für die Kommunikation nicht die höchste Geheimhaltungsstufe notwendig. Daher ist das Prinzip Vertrauen beim ersten Kontakt (Trust on first use; TOFU) ausreichend und man vertraut einfach dem Schlüssel, den man beim ersten Mal bekommt.

Dieser erste Schlüssel gilt dann aber als gesetzt und bei WhatsApp kommt es zu der Warnung »Die Sicherheitsnummer von … hat sich geändert.«, wenn der Gesprächspartner sich (z. B. durch Neuinstallation) einen neuen Schlüssel generiert. Bei WhatsApp nichts ungewöhnliches, aber im Allgemeinen sollte dies einen stutzen lassen. Bei Matrix kenne ich die Anzeige nicht, da ich einen solchen Fall noch nicht erlebt habe.

Für beide Systeme gibt es jedenfalls auch die höheren Sicherheitsstufen, indem man über die Kontaktinformationen eine Verifikation anstößt. Entweder vergleicht man den Fingerprint – die lange Sicherheitsnummer – oder nutzt den QR-Code. Bei Matrix gibt es noch die weitere schöne Variante, Symbole zu vergleichen. Diese sind nur eine andere Form des Fingerprints, aber wesentlich leichter zu vergleichen.

Die Verschlüsselung hat sich bei dieses Systemen wesentlich besser als bei E-Mail durchgesetzt, weil die Anforderungen an die Schlüsselprüfung recht gering sind, aber auf Bedarf erhöht werden können. Durch die Entwicklungen über die Zeit hin, haben sich aber auch für die neuen System bessere Möglichkeiten zum Schlüsselaustausch ergeben, die E-Mail mit PGP in der Anfangszeit nicht hatte.

Web Key Directory für PGP-Schlüssel

Für den Austausch von PGP-Schlüsseln wurden früher Key-Server genutzt, die aber schon immer einige Nachteile hatten und mittlerweile durch konkrete Angriffe dagegen nicht mehr sicher einsetzbar. Da sich aber durch die Initiative Let's encrypt in der Zwischenzeit die TLS-Verschlüsselung (und Inhaberprüfung) für das Web sehr stark verbreitet hat, bietet sich der Weg darüber an: Wer einen TLS-gesicherten Webserver unter einer bestimmten Domain betreibt, hat sehr wahrscheinlich auch Zugriff auf die Postfächer dieser Domain und somit kann dieser Quelle hinreichend vertraut werden.

Die Idee von Web Key Directory (WKD) ist also auf einer Webseite für die E-Mailadressen der Domain in dem Verzeichnis /.well-known/openpgpkey/hu/ die öffentlichen Schlüssel zu abzulegen. Als Dateiname wird aber nicht der Name des Postfachs, sondern ein Hash verwendet, den man sich mit gpg ermitteln kann (Anleitung).

% gpg --with-wkd-hash --list-key joerg@jo-so.de
pub   dsa3072 2018-10-11 [SC]
uid        [ ultimativ ] Jörg Sommer <joerg@jo-so.de>
           61x1wzugy6d57cqoyc9kikxo4w33kzdy@jo-so.de
% gpg --no-armor --export joerg@jo-so.de --output .well-known/openpgpkey/hu/61x1wzugy6d57cqoyc9kikxo4w33kzdy

Prüfen kann man das ganze dann auf folgendem Weg:

% mkdir -m 0700 /tmp/gpg-work
% export GNUPGHOME=/tmp/gpg-work
% gpg --list-keys
gpg: Die "Keybox" `/tmp/gpg-work/pubring.kbx' wurde erstellt
gpg: /tmp/gpg-work/trustdb.gpg: trust-db erzeugt
% gpg --auto-key-locate clear,wkd --locate-keys joerg@jo-so.de
gpg: Schlüssel 7D2C9A23D1AEA375: Öffentlicher Schlüssel "Jörg Sommer <joerg@jo-so.de>" importiert
gpg: Anzahl insgesamt bearbeiteter Schlüssel: 1
gpg:                              importiert: 1
gpg: keine ultimativ vertrauenswürdigen Schlüssel gefunden
pub   dsa3072 2018-10-11 [SC]
      B5A58C5DD13FFAED87A357217D2C9A23D1AEA375
uid        [ unbekannt ] Jörg Sommer <joerg@jo-so.de>
sub   elg3072 2018-10-11 [E]

Wie im Beispiel oben zu sehen ist, kann mit gpg --locate-keys … ganz einfach der Schlüssel abgerufen werden und die neueren Versionen von Thunderbird unterstützen WKD ebenfalls.

Ein Vorteil an WKD ist die Kontrolle über die Veröffentlichung. Bei einem Key-Server kann jeder seine Signatur zu Bestätigung des Schlüssels veröffentlichen – auch völlig schwachsinnige und diffamierende Einträge, die dann immer mit dem Schlüssel vom Server geladen werden. Auf dem eigenen Webserver hat man jedoch die Kontrolle darüber und kann auch sicherstellen, dass Veränderungen des Schlüssels (z. B. ein Ungültigmachen) ordnungsgemäß publiziert werden.

OPENPGPKEY im DNS

Neben der Verteilung des Schlüssels per HTTP kann man auch seinen PGP-Schlüssel über das Domain-Name-System verteilen. Hierzu gibt es mit RFC 7929 den speziellen Typ OPENPGPKEY. In der Unterzone _openpgpkey muss man einen Eintrag mit den ersten 56 Stellen (28 Bytes) der SHA-256-Summe des Benutzernamens anlegen und dort den öffentlichen Schlüssel hinterlegen:

% host -t OPENPGPKEY 56f802d50f72640595e9b894180ead6d029a2953eb791a21e1b4c6e0._openpgpkey.jo-so.de                     
56f8…c6e0._openpgpkey.jo-so.de has OPENPGPKEY record 9904ae…b4c6e5

% gpg --locate-keys --auto-key-locate dane joerg@jo-so.de
gpg: Bitte ein --check-trustdb durchführen
pub   dsa3072 2018-10-11 [SC]
      B5A58C5DD13FFAED87A357217D2C9A23D1AEA375
uid        [ ultimativ ] Jörg Sommer <joerg@jo-so.de>
sub   elg3072 2018-10-11 [E]

Den Inhalt des Eintrags kann man sich direkt von gpg ausgeben lassen, wobei gpg noch den Typ TYPE61 verwendet. Daher als Inhalt nur den Teil innerhalb der Klammern verwenden:

% gpg --export-options export-dane --export joerg@jo-so.de \
  |sed ': start; /)/q;  /(/ { s/\n\t//; N; b start; }'
$ORIGIN _openpgpkey.jo-so.de.
; B5A58C5DD13FFAED87A357217D2C9A23D1AEA375
; Jörg Sommer <joerg@jo-so.de>
56f802d50f72640595e9b894180ead6d029a2953eb791a21e1b4c6e0 TYPE61 \# 2284 (9904ae045b…22e2cca220)

In der gpg.conf sollte man noch auto-key-locate local,wkd,dane eintragen, damit bei gpg --locate-keys automatisch der DNS-Eintrag abgefragt wird. Die Einträge im DNS sind allerdings nicht so umfangreich und enthalten keine Unterschriften, weshalb die Verteilung per WKD vorzuziehen ist.

Zentrales WKD bei openpgp.org

TOFU mit GnuPG

Auf GnuPG unterstützt das TOFU-Modell und kann es auch gemeinsam mit dem Web-of-Trust-Modell nutzen. Hierfür braucht man in der Konfigurationsdatei ~/.gnupg/gpg.conf nur den Eintrag trust-model tofu+pgp (manpage) setzen. Ein neu beobachteter Schlüssel bekommt dann die Einstufung etwas vertrauenswürdig. Sollte ein zweiter Schlüssel für die selbe Adresse auftauchen, werden beide als unsicher markiert und es wird eine Warnung ausgegeben.

Wenn man von der Gültigkeit eines Schlüssels überzeugt ist, kann man diesen mit gpg --tofu-policy good <KEY-ID> als vertrauenswürdig einstufen. Sollte ein Schlüssel als kompromittiert bekannt sein, kann man ihn mit gpg --tofu-policy bad <KEY-ID> als schlecht einstufen.

Verschlüsselte Header mit Neomutt

Eine E-Mail hat die übliche Struktur wie viele andere Formate auch und untergliedert sich in einen Kopf (Head) mit Metadaten und einen Rumpf (Body) mit den Nutzdaten. Die Metadaten zur E-Mail sind aber nicht wie der Rumpf durch die PGP-Verschlüsselung geschützt. Viele der Angaben, insbesondere der Betreff sind für die Übertragung nicht notwendig, weshalb es den Vorschlag (alte Fassung, IETF-Seite) gibt, diese Felder mit belanglosen Angaben zu füllen und innerhalb des Rumpfes die echten Angaben zu übertragen.

Für Neomutt ist mit der Version 2019-10-25 auch die Unterstützung hinzugekommen und kann mit set crypt_protected_headers_write in der Konfiguration aktiviert werden. Thunderbird kann mit diesen verschlüsselten Headern schon länger umgehen.

Schlüsseladresse in der Mailadresse hinterlegen

Es gibt zwei Wegen, auf denen man dem Empfänger einer E-Mail gezielt die Adresse des PGP-Schlüssels mitteilen: direkt in der Nachricht oder über Kopffelder der E-Mail.

Key-Server mit GPG

Der verschlüsselte Text hat auch eine standardisierte Struktur und ist nicht einfach ein buntes Wirrwarr. Innerhalb der Struktur sind auch Felder vorgesehen, über die man mitteilen kann, wo der öffentliche Schlüsselteil des privaten Teils, der zur Verschlüsselung verwendet wurde, zu finden ist. Bei gpg kann man diese Feld mit der Option --sig-keyserver-url beim Aufruf oder der gleichnamigen Einstellung in der Konfiguration ~/.gnupg/gpg.conf setzen:

sig-keyserver-url https://jo-so.de/pgp-key.txt

Dieses Feld kann auch genutzt werden, wenn man Dateien verschlüsselt oder signiert. Wenn eine solche Signatur auf einem Server liegt, ist meist nicht klar, woher man den Schlüssel zur Prüfung beziehen kann. Genau da hilft dieses Feld. Wenn man zur Prüfung die Optionen --auto-key-retrieve --keyserver-options honor-keyserver-url angibt, holt gpg automatisch den Schlüssel, sollte er fehlen.

OpenPGP-Feld für E-Mails

Den Ort des Schlüssels kann man auch über in der E-Mail über das Kopffeld OpenPGP angeben. Thunderbird setzt dieses automatisch, wenn man einen Schlüssel verwendet. Bei Neomutt kann man dies mit my_hdr OpenPGP: … festlegen. Da ich zwei unterschiedliche Schlüssel verwende, wechsle ich dieses Feld immer entsprechend der Absenderadresse:

send2-hook . 'my_hdr OpenPGP: id=C1ED266701F55480\; url=https://jo-so.de/pgp-key-alea.txt\; preference=signencrypt'
send2-hook '~f @jo-so\.de' 'my_hdr OpenPGP: id=7D2C9A23D1AEA375\; url=https://jo-so.de/pgp-key.txt\; preference=signencrypt'

PGP-Schlüsselverwaltung im CA-Stil

OpenPGP arbeitet mit einem Netzwerk zur Einstufung der Vertrauenswürdigkeit eines Schlüssels; Web of trust genannt. Dabei können Schlüsseleigentümer sich kreuz und quer die Gültigkeit bestätigten. TLS für HTTPS bzw. S/MIME verfolgen einen hierarchischer Ansatz, bei dem eine zentrale Instanz die Gültigkeit ihr untergeordneter Schlüssel bestätigt. Für Firmen ist zum Beispiel eine solche Struktur von Vorteil, weil es die Verwaltung innerhalb der Firma erleichtert.

Da ein Netzwerk auch leicht in eine hierarchische Struktur (einen Baum) überführt werden kann, unterstützt OpenPGP auch das CA-Modell mit zentraler Instanz. Ein Programm für die Unterstützung dieses Modells wurde mit OpenPGP CA geschaffen.