Lustige Cryptodinge mit GPG

Eine Zusammenfassung

Wieso verschlüsseln?

Weil mans kann? Naja, nicht nur deswegen. Der Umgang mit Kryptographie - insbesondere asymmetrischer Kryptographie - will gelernt sein, es kann immer mal passieren, dass es aus irgendwelchen Gründen nötig wird, Informationen über einen gesicherten Kanal auszutauschen - seien es Passwörter, geheime Regierungsunterlagen oder Nacktbilder.

Wie verschlüsseln?

Dieser Abschnitt erzählt nur ein paar Krypto-Hintergründe und kann prinzipiell übersprungen werden.

Grundsätzlich unterscheidet man 2 Typen der Kryptographie:
  • Symmetrische Kryptographie

    Ver- und Entschlüsselung benutzen den selben Schlüssel, dieser muss also sowohl dem Sender als auch dem Empfänger vorher bekannt sein und in irgendeiner Form ausgetauscht werden - auch über einen möglichst sicheren Kanal. Vorteile sind wohl die einfachere Umsetzung und Implementierung sowie "beweisbarere" Sicherheit und bessere Performance.
  • Asymmetrische (aka Public-Key) Kryptographie

    Der für "dynamischere" Kommunikation interessantere Teil (und auch der um den sich dieses Dokument hauptsächlich dreht). Hierbei existieren für einen Schlüssel zwei Teile, nämlich ein privater (geheimer) Teil, der (im besten Fall) nur dem Besitzer bekannt ist und ein öffentlicher Teil, der jedem bekannt sein darf - und je nach System auch möglichst weit verbreitet werden soll. Algorithmen für asymmetrische Krypto sind eher komplex und langsam, daher nutzen sie viele Protokolle um zu Beginn einen gemeinsamen Schlüssel auszutauschen, mit welchem dann die folgende Kommunikation symmetrisch verschlüsselt wird.

Welche Tools brauche ich?

Hier unterscheiden sich die beiden grossen Betriebssysteme etwas. Der Standard für Kommunikation mit asymmetrischer Kryptographie ist der von Phil Zimmerman entwickelte OpenPGP-Standard und seine Implementationen PGP (das "Original", gekauft von Symantec) und GnuPG (Quelloffene, kostenlose Software (FOSS)).
  • Linux

    Die meisten Distributionen haben GnuPG in ihren Paketarchiven; am bequemsten ist es daher, den Paketmanager der Wahl dazu zu bewegen, GnuPG zu installieren. Für Leute, die sich mit der Kommandozeile wohl fühlen, reicht hierbei die Versionsreihe 1.x vollkommen aus. Diese ist kleiner und hat weniger Abhängigkeiten. Für nicht so text-feste Anwender empfiehlt sich die Versionsreihe 2.x, die sich mehr in die grafische Umgebung einfügt (besonders bei der Passworteingabe).

    Beispiel Debian:
    apt-get install gnupg
    bzw
    apt-get install gnupg2

  • Windows

    Man könnte sich natürlich die "Originalversion" von PGP kaufen, aber hey, wer will schon Geld ausgeben? ;) Es gibt einen Windows-Port von GnuPG (gesponsert/betreut vom BSI - nicht sicher was man davon halten soll...), welches sich aber nur unter Schmerzen davon überzeugen lässt, sein Interface auf Englisch auszugeben - wer allerdings gerne deutsche Oberflächen hat, dürfte hier glücklich werden. Der Installer vom BSI zieht auch die Windows-Version von Kleopatra (einen grafischen Schlüsselmanager aus dem KDE-Projekt) mit nach, der einige Techniken die in diesem Dokument später beschrieben werden (zb. Offline-Masterkeys) nicht oder nur teilweise unterstützt. Es wäre daher wohl (auch unter Sicherheitsaspekten) eine gute Idee, zumindest die Key-Erzeugung mit einem (Live-)Linux-System vorzunehmen.

    Es ist wohl auch möglich GnuPG unter Cygwin zu bauen, wenn man sich diesen Spass gönnen will.

Was ist ein GPG-Key(pair)?

Eine der Grundeinheiten des GPG-Ökosystems ist der GPG-Key (bzw das GPG-Keypair, bestehend aus einem privaten und einem öffentlichen Teil), der lose gesagt die Repräsentation eines Benutzers (bzw. eines Individuums) darstellt.

Der Begriff des "Key" ist im PGP-Jargon doppeldeutig: Er kann sowohl eine komplette Identität meinen, als auch einen spezifischen kryptographischen Schlüssel. Ein "Identitätsschlüssel" kann mehrere "Kryptographieschlüssel", auch mit unterschiedlichen Anwendungsbereichen (Signieren, Verschlüsseln) und Algorithmen (RSA, DSA, ElGamal) besitzen. Jeder Kryptographie-Schlüssel hat einen eigenen öffentlichen sowie privaten Teil, Der öffentliche Teil des Identitätsschlüssel bezeichnet dann alle öffentlichen Teile der in ihm enthaltenen Kryptographieschlüssel, analog mit dem privaten Teil.
Der Fingerprint des Haupt-Kryptographieschlüssels wird meist stellvertretend als Identifikation des Identitätsschlüssels verwendet.

Ein GPG-Key enthält mehrere Untereinheiten:
  • Hauptschlüssel

    Der primäre Schlüssel am Keypair (meist ein Signatur-Key) wird oft als Haupt-Identifikationsmerkmal fuer den gesamten Schlüssel verwendet.
  • User-IDs (UIDs)

    Ein Key kann viele verschiedene Identitäten eines einzelnen Benutzers enthalten. Eine UID besteht aus einem Namen, einer Emailadresse und einem Kommentar. Nur das Namensfeld ist zwingend erforderlich, die anderen beiden sind optional.

    Im Normalfall hat ein Key eine UID für jede Emailadresse, auf der der Benutzer verschlüsselte/signierte Kommunikation senden oder empfangen möchte. UIDs werden besonders im Zusammenhang mit dem Web of Trust zu wichtigen Merkmalen eines Keys.

    UIDs haben jedoch keinen kryptographischen Einfluss auf den Schlüssel, sondern gelten nur als Identifikationsmöglichkeit (bedeutet: Es wird nicht an eine bestimmte UID verschlüsselt, sondern an einen bestimmten Krypto-Key).

    Der Besitzer eines Keys kann diesem während seiner Lebenszeit unbegrenzt viele UIDs hinzufügen und diese auch wieder "zurückrufen" (revoken). Es ist zwar möglich eine UID von einem Key zu löschen, jedoch werden Keys normalerweise additiv importiert - sprich, hat ein anderer User den öffentlichen Schlüssel in einer Version, in der die gelöschte UID noch existiert, so wird diese beim Import der neuen Version nicht gelöscht, sondern existiert weiter.

  • Subkeys

    Ein Schlüsselpaar kann beliebig viele "Unterschlüssel" besitzen - mit jeweils eigenen Schlüsselalgorithmen, Ablaufdaten, Schlüssellängen und Fingerprints. Trotzdem sind diese Subkeys mathematisch Teil des übergeordneten Schlüssels. Ihre privaten Teile können jedoch unabhängig von denen des Hauptschlüssels exportiert und verwendet werden, wodurch sich einige Verbesserungen in der Benutzbarkeit ergeben.

    Genau wie UIDs kann der Besitzer eines Schlüssels diesem während seiner Lebenszeit beliebig viele Subkeys hinzufügen und diese auch wieder zurückrufen.

    Anders als UIDs sind Subkeys jedoch kryptographisch relevant: Sie besitzen einen eigenen eindeutigen Fingerprint und an sie kann speziell verschlüsselt (Encryption-Subkeys) oder mit ihnen signiert (Signing-Subkeys) werden.
  • Photo IDs

    Es ist auch möglich, kleinere Bilddateien an Schlüssel anzuhängen. Diese können bspw. als weiteres Verifikationsmedium für die Identität eines Schlüsselinhabers genutzt werden.

Vorbereitungen & Notwendigkeiten

Mangels Erfahrung mit Alternativen werden wir uns hier auf den Umgang mit GnuPG unter Linux-Systemen beschränken. Ein bisschen Erfahrung mit der Kommandozeile muss leider auch vorausgesetzt werden, obwohl wir unser bestes tun werden, die Befehle zu erklären.

Für die Erstellung eines guten™ Schlüsselpaares empfiehlt es sich, eine "sichere" Maschine zu benutzen - also ein System, bei dem man davon ausgehen kann, dass es bisher "überwachungsfrei" ist und welches möglichst wenig Angriffsfläche bietet.

Hierzu bieten sich einige Möglichkeiten:

  • Livesysteme

    Es gibt einige Linux-Distributionen (oder auch BSD, falls jemand das lieber ist), die Live-Medien anbieten (bspw. Tails, grml) - also bootbare USB-Sticks oder CDs die schon alles nötige für GPG an Bord haben (und im Idealfall auch nicht mehr als das).
  • Ein Offline-/Airgapped-System

    Bei dieser Methode verwendet man einen Computer (am sinnvollsten einen Laptop) nur für diesen Zweck. Er wird einmal mit einem minimalen System (von einem vertrauenswürdigen Medium) installiert und darf niemals eine Internetverbindung haben - daher der Name "Airgap".
Generell empfiehlt es sich, auf dem System der Wahl möglichst wenige Prozesse aktiv zu haben (bspw. nur Textsystem), während der Erzeugung keine physische Netzwerkverbindung zu haben (Kabel ziehen!) und die sensitiven Daten bspw. auf einem verschlüsselten USB-Stick (mit einer Partition, die nie an "unsicheren" Systemen gemountet wird und einer, die dazu dient, Daten auf "potentiell sichere" Systeme zu übertragen) zu speichern.

Um ein solches sicheres Speichermedium zu erzeugen, empfiehlt sich die Verwendung eines neuen USB-Sticks aus einer vertrauenswürdigen Quelle (bspw. ein zufällig ausgewählter Elektronikmarkt). Um zusätzlichen Schutz zum Beispiel bei Verlust zu schaffen, sollte mindestens eine Partition auf diesem Medium verschlüsselt sein (zum Beispiel mit LUKS). Möglicherweise kann die Einrichtung einer unverschluesselten Partition zum Transfer von bspw. Öffentlichen Schlüsseln sinnvoll sein, dafür kann aber auch einfach ein weiterer USB-Stick verwendet werden.

Jetzt noch einige Worte dazu, wie GPG Schlüssel auf der Platte verwaltet:
Von Haus aus benutzt GPG das Verzeichnis .gnupg/ im Home-Ordner des jeweiligen Benutzers, um alle Daten zu speichern. Schlüssel werden dabei in sogenannten "Keyrings" organisiert, die man sich als Container für mehrere Schlüssel vorstellen kann. Folgende Dateien finden sich im Normalfall mindestens in ~/.gnupg/:

  • secring.gpg - Enthält die privaten Teile von Schlüsseln, wo sie bekannt sind.
  • pubring.gpg - Enthält alle öffentlichen Schlüssel.
  • trustdb.gpg - Enthält Informationen darüber, zu welchem Grad bestimmten Schlüsseln vertraut wird.
pubring.gpg und secring.gpg werden von GnuPG standardmässig als Keyrings verwendet. Natürlich ist es auf einem Livesystem eher ungewollt, diese Dateien im Homeverzeichnis zu haben, daher macht es Sinn sich bspw. einen verschlüsselten USB-Stick zu bauen und das Master-Keypair dort zu speichern. Dazu legen wir auf dem sicheren Speichermedium einen Ordner names gpg_home an, welchen wir später an GPG als temporäres Homeverzeichnis übergeben.

Innerhalb dieses Homeverzeichnisses kann auch die Konfiguration von GPG angepasst werden, was uns die spätere Übergabe einiger Kommandozeilenparameter erspart.
Hierzu legt man darin eine Datei namens gpg.conf an, in welcher dann zeilenweise Optionen angegeben werden können.

Beispielhaft seien hierbei folgende Optionen genannt

  • no-emit-version

    Keine Versions-/Programmkennzeichen in Ausgabetexte einbetten
  • default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed

    Erspart uns das Setzen der Algorithmenpräferenzliste über die Kommandozeile
  • ask-cert-level

    Beim signieren eines Schlüssels nach der Vertrauensstufe fragen

Wie erzeuge ich mein Keypair?

Mangels Erfahrung mit Alternativen werden wir uns hier auf den Umgang mit GnuPG unter Linux-Systemen beschränken. Ein bisschen Erfahrung mit der Kommandozeile muss leider auch vorausgesetzt werden, obwohl wir unser bestes tun werden, die Befehle zu erklären.

Diese Anleitung versucht, ein möglichst sicheres Schema für die Benutzung einer Identität auch auf mehreren Geräten zu beschreiben. Ein einfacher Schlüssel ohne weitere Sicherheitsvorkehrungen kann mit dem Befehl gpg --gen-key interaktiv erzeugt werden.

Wir werden in dieser Anleitung ein Keypair mit mehreren Subkeys (siehe oben) erzeugen - in unserem Fall mit einem Encryption-Subkey (wer sich der Implikationen bewusst ist kann auch gerne mehrere Encryption-Subkeys erzeugen) sowie einem Signing-Subkey pro Gerät auf dem der Schlüssel verwendet werden soll.

Die einzelnen Geräte sollen dabei auch nur die geheimen Teile ihrer jeweiligen Subkeys besitzen, sodass selbst wenn eines der Geräte kompromittiert (verloren, überwacht, gelöscht) wird, der Besitzer mit dem Master-Keypair problemlos nur diesen einzelnen Subkey revoken kann und dabei nicht automatisch das gesamte Keypair verliert oder die Sicherheit der anderen Geräte aufs Spiel setzt.

Damit kommen wir auch schon zum Hauptteil. Die nachfolgenden Schritte sollten nacheinander auf dem vorher erwähnten sicheren System (mit gemountetem sicheren Storage-Medium) ausgeführt werden.

  1. GNUPGHOME setzen

    Damit unsere Schlüssel nicht auf der Platte oder im temporären Homeverzeichnis unseres Livesystems landen, setzen wir mit
    user@box:~$ export GNUPGHOME=/media/meinSicheresMedium/gpg_home
    eine Umgebungsvariable, die GPG anweist, seine Dateien auf unserem sicheren Medium zu speichern. Der Ordner sollte die Zugriffsmaske 700 (Besitzer: lesen, schreiben, ausführen; Gruppe: keine; Alle: keine) besitzen, ansonsten kann es sein dass GPG bei manchen Befehlen wegen "unsicherer Zugriffsrechte" den Dienst verweigert.
  2. Master-Keypair generieren

    Mit dem Befehl
    user@box:~$ gpg --gen-key
    starten wir den Assistenten zur Schlüsselerzeugung. GPG führt uns nun durch einige Abfragen, die den neuen Key betreffen. Wir möchten einen Schlüssel, der sowohl signieren als auch verschlüsseln kann. In unserem Fall kann man diesen sogar unbegrenzt gelten lassen, da wir uns gleich noch einige Rettungsseile basteln werden und der Master-Key relativ sicher sein wird. Als erste UID reicht im Zweifelsfall auch der Name ohne Email-Adresse oder Kommentar (wir werden später noch Gelegenheit haben, andere hinzuzufügen). Als Passphrase sollten wir hier eine möglichst komplexe Zeichenfolge aussuchen. Die Gerätespezifischen Schlüssel werden eigene Passphrasen bekommen.
  3. Präferierte Algorithmen & weitere UIDs

    Jetzt werden wir den gerade erstellten Schlüssel bearbeiten, um einige Einstellungen vorzunehmen und weitere UIDs hinzuzufügen.
    user@box:~$ gpg --edit-key <identifier>
    <identifier> kann hierbei sein:
    • (Teil-)Fingerprint
    • Teile der UID
    GPG präsentiert uns nun sein interaktives Interface. Wir führen darin folgenden Befehl aus, um die bevorzugten Algorithmen etwas zu stärken (dieser Schritt kann ausgelassen werden, falls die Präferenzen bereits wie oben in gpg.conf gesetzt wurde):
    gpg> setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
    GPG fragt uns nach der Passphrase, welche wir uns natürlich mittlerweile auswendig gemerkt haben ;). Danach können auf der GPG-Kommandozeile mit
    gpg> adduid
    weitere UIDs interaktiv hinzugefügt werden. Abschliessend speichern wir unsere Änderungen mit einem
    gpg> save
  4. Subkeys hinzufügen

    Wir beginnen wieder mit
    user@box:~$ gpg --edit-key <identifier>
    unseren Key zu bearbeiten. Diesmal starten wir mit
    gpg> addkey
    den Assistent für das hinzufügen eines Subkeys. Wir entsperren hierfür unseren Schlüssel wie gehabt mit der Passphrase und wählen dann den Typ, den unser neuer Subkey haben soll - in unserem Fall dann ein "Sign only"-Key. Es ist auch möglich, einen Encryption-Subkey pro Gerät zu erstellen - nur muss dies demjenigen, der an den Besitzer verschlüsselt, kommuniziert werden. Dateien, die an einen bestimmten Subkey verschlüsselt sind, können auch nur mit dessen privaten Teil entschlüsselt werden.
    Den Subkeys geben wir in unserem Fall am besten eine Lebenszeit von 2 Jahren - nach denen dem Master-Key dann problemlos neue hinzugefügt und diese dann die alten auf den Geräten ersetzen.
    Haben wir alle unsere Subkeys erzeugt, speichern wir unsere Änderungen mit einem
    gpg> save
  5. Revocation Certificate generieren

    Um das komplette Master-Keypair im Notfall (bspw. geheime Teile komplett verloren) zurückrufen zu können, erzeugen wir jetzt ein sogenanntes "Revocation Certificate" mit
    user@box:~$ gpg --gen-revoke <identifier> > /media/meinSicheresMedium/master-pair.revcert
    Die entstandene Datei sollten wir wenn irgendwie möglich auch auf einem sicheren Drucker drucken (ist nicht übermässig gross) und danach irgendwo sicher aufbewahren. Im äussersten Notfall können wir das Revocation Certificate dann abtippen, importieren und an die Keyserver senden, um unser Master-Keypair als ungültig zu markieren.
  6. Komplettes Master-Keypair exportieren

    Als nächstes werden wir das komplette Master-Keypair, inklusive der Subkey-Secrets exportieren.
    user@box:~$ gpg --export --armor --no-emit-version <identifier> > /media/unsichererTeil/mein-key.asc
    user@box:~$ gpg --export-secret-keys --armor <identifier> > /media/meinSicheresMedium/master.secret-key

    Die resultierende .secret-key Datei ist der wichtigste Teil der ganzen Übung. Bekommt ein Angreifer sie in die Hand, haben wir verloren (bis auf die Passphrase, allerdings ist das je nach Angreifer eine minimale Barriere) und die einzige Chance ist das Revocation Certificate.
    Die .asc Datei ist unser öffentlicher Schlüssel, weswegen wir ihn auch auf den "unsicheren" Teil unseres Speichermediums exportiert haben. Eine Kopie im sicheren Teil vorzuhalten schadet jedoch nicht.
  7. Subkeys einzeln exportieren & Passphrasen anpassen

    In diesem Schritt werden wir nun die Dateien erzeugen, die wir auf die einzelnen Geräte verteilen werden. Hierzu müssen wir uns entscheiden, welche Subkeys auf welchem Gerät verfügbar sein sollen. Um Dateien/Texte zu signieren und verschlüsselte Dateien zu versenden, genügt ein Signing-Subkey. Soll das Gerät auch verschlüsselte Dateien empfangen und entschlüsseln sollen, so wird ein Encryption-Subkey benötigt.

    Hierbei müssen wir beachten, dass verschlüsselte Dateien immer nur mit dem Subkey entschlüsselt werden können, an den sie auch verschlüsselt wurden. Es besteht zwar die Möglichkeit, an mehrere Subkeys zu verschlüsseln, jedoch muss dies dem Sender kommuniziert werden (und wird nicht von jeder Software unterstützt). Am einfachsten ist es daher, einen Encryption-Subkey am Master-Keypair zu haben, und diesen nur auf Geräten, denen zumindest grundlegend vertraut wird, zu verwenden.

    Um die Passphrase anzupassen, begeben wir uns wieder in den Bearbeitungsmodus:
    user@box:~$ gpg --edit-key <identifier>
    und starten mit
    gpg> passwd
    den Assistenten zum ändern der Passphrase und ändern diese in unsere "Gerätepassphrase". Wir speichern wie gewohnt unsere Änderungen mit
    gpg> save
    Danach exportieren wir mit
    user@box:~$ gpg --armor --export-secret-subkeys <subfp1>! <subfp2>! > /media/meinSicheresMedium/geraetN.subkey-secrets
    nacheinander die Subkeys für die einzelnen Geräte. subfpN bezeichnet hierbei die Fingerprints der Subkeys, die exportiert werden sollen. Die Ausrufezeichen nach den Fingerprints sind wichtig (sonst exportiert GPG aus unerfindlichen Gründen alle Subkey-Secrets)!
    Natürlich können wir auch pro Gerät eine eigene Passphrase festlegen - dazu müssen wir nur vor jedem Export die Passphrase ändern.
  8. Komplettes Master-Keypair wieder in secring.gpg importieren

    Statt uns die Mühe zu machen, die Passphrase des Master-Keypairs wieder zurück zu ändern, löschen wir es einfach mit dem Befehl
    user@box:~$ gpg --delete-secret-key <identifier>
    vom Keyring und importieren es danach mit
    user@box:~$ gpg --import /media/meinSicheresMedium/master.secret-key
    komplett neu.
  9. Geräte-Keypairs importieren

    Auf den jeweiligen Geräten können jetzt die .subkey-secret Dateien importiert werden. Die Ausgabe des Befehls
    user@box:~$ gpg --list-secret-keys
    sollte dabei jetzt sec# am Hauptschlüssel anzeigen, was bedeutet dass der geheime Schlüssel für das Master-Pair nicht vorhanden ist - wohl aber der für bestimmte Subkeys.
Damit haben wir uns ein ziemlich gutes™ Keypair gebaut! Wenn wir den öffentlichen Teil des Master-Keys jetzt auf einer "unsicheren" Maschine mit
user@box:~$ gpg --import /media/unsichererTeil/mein-key.asc
wieder importieren und mit
user@box:~$ gpg --send-keys <fingerprint>
an einen Keyserver schicken, können uns auch andere Menschen finden. Alternativ (oder auch zusätzlich) kann man natürlich den öffentlichen Teil auch auf seiner Homepage zum Download anbieten.

Wie verschlüssele/entschlüssele/signiere ich?

Damit kommen wir jetzt zur konkreten Anwendung von GnuPG - also dem eigentlich interessanten Teil ;)

Für bestimmte Protokolle/Vorgänge bei denen GPG eingesetzt werden kann, gibt es auch eigene Tools, die die Benutzung einfacher machen - beispielsweise das Enigmail-Plugin für Thunderbird.
Die Benutzung dieser Tools sollte meist entweder selbsterklärend sein, oder den jeweiligen manpages oder README-Files entnehmen zu sein.
Wir werden uns hier wieder auf die Benutzung von GPG mit der Kommandozeile unter Linux beschränken. Solltest du jedoch Muse haben, einige Absätze über ein bestimmtes Tool zu schreiben, bist du herzlich Willkommen, diese zu diesem Dokument beizutragen!

Sollte es uns eines Tages zu Mühselig werden, für jede einzelne Aktion unseren Key mit unserer Passphrase zu entsperren, lohnt sich ein Blick auf gpg-agent. Der Agent erlaubt uns, unser Keypair einmal zu entsperren, hält es danach für eine bestimmte Zeit in entsperrter Form vor und erspart uns so etwas Tipparbeit.

Die folgenden Vorgehensweisen funktionieren mit den Gerätesubkeys, die Nutzung des Master-Keys ist (ausser wenn an diesen verschlüsselt wurde) nicht notwendig.

Signieren & Verifizieren

Um einen kryptographischen "Beweis" anzufertigen, dass wir Urheber eines bestimmten Dokumentes bzw. einer Datei sind und diese Datei auch zwischenzeitlich nicht verändert wurde, können wir mit GPG eine Signatur für eine Datei erzeugen. Hierzu benötigen wir einen Signing-Key dessen privaten Teil wir besitzen (e.g. unser gerätespezifischer Signing-Subkey) und führen dann folgenen Befehl aus:
user@box:~$ gpg --detach-sign <filename>
GPG erzeugt nun eine binäre Signatur und speichert sie in der Datei <filename>.sig.
Um eine Signatur einer Datei auch in normalen Texten einbetten zu können, ist es meist sinnvoller, die Signatur in einem ASCII-basierten Format ausgeben zu lassen. Dies erreichen wir mit
user@box:~$ gpg --armor --no-emit-version --detach-sign <filename>
Dieser Befehl erzeugt die Datei <filename>.asc, welche eine ASCII-Form der Signatur enthält.
Ist die zu signierende Datei eine Textdatei, so kann die Signatur auch direkt an die Nachricht angehängt werden. Dies geschieht mittels
user@box:~$ gpg --no-emit-version --clearsign <filename>
was wiederum die Datei <filename>.asc erzeugt, diesmal aber mit der Originaldatei gefolgt von ihrer Signatur.

Soll mit einem anderen Schlüssel als mit dem Standardschlüssel signiert werden, kann dies mit dem Parameter --default-key <fingerprint> eingestellt werden.

Um die Signatur einer Datei zu verifizieren, müssen wir den öffentlichen Schlüssel des Schlüsselpaares besitzen, mit dem die Datei signiert wurde (beispielweise via Download von einem Keyserver). Danach können wir mit einem
user@box:~$ gpg --verify <filename>.asc <filename>
überprüfen, ob die vorhandene Datei derjenigen entspricht, die ursprünglich signiert wurde.

Verschlüsseln & Entschlüsseln

Um eine Datei (oder eine Nachricht) an einen bestimmen Empfänger zu verschlüsseln, benötigen wir dessen Public Key (Tatsächlich benötigen wir dazu nicht einmal ein eigenes Keypair). Führen wir dann folgenden Befehl aus:
user@box:~$ gpg --recipient <identifier> --encrypt <filename>
so erzeugt uns GPG die Datei <filename>.gpg, die dann nur von den angegebenen Empfängern dekodierbar ist. Wir können auch mehreren Empfängern das Entschlüsseln ermöglichen, indem wir mehrmals --recipient <identifier> angeben (Es kann sinnvoll sein, Dateien auch zusätzlich noch an sich selbst zu verschlüsseln).

Die hierbei enstehenden Dateien sind Binärdateien, und können daher nicht ohne weiteres bspw. in Emails eingefügt werden. Mit dem zusätzlichen Parameter --armor weisen wir GPG an, die verschlüsselte Datei in einem textbasierten Format zu speichern - es wird dann entsprechend die Datei <filename>.asc erzeugt. Das kodieren der Binärdaten als Text (intern indirekt Base64) führt dazu, dass das Resultat ein wenig mehr Speicher als die binär kodierte Variante benötigt.

GPG kann auch für symmetrische Verschlüsselung verwendet werden - hierbei benötigt man dann einen bereits vorher ausgetauschten Schlüssel, der allen kommunizierenden Parteien bekannt ist - daher der Name "symmetrisch".

Um eine Datei symmetrisch zu verschlüsseln, setzen wir folgenden Befehl ein:
user@box:~$ gpg --symmetric <filename>
GPG erfragt dann den zu verwendenden Schlüssel von uns, inklusive einer Wiederholung zur Sicherheit. Wenn gewollt kann mit der Option --cipher-algo <algorithmus> der zu verwendende symmetrische Algorithmus angegeben werden. Die symmetrische Verschlüsselung azeptiert auch die --armor-Option zur Ausgabe von ASCII-kodiertem Text. Auch die Entschlüsselung der entstehenden Dateien funktioniert mit demselben Befehl wie für asymmetrisch verschlüsselte Dateien.

Die beiden Verschlüsselungsmodi lassen sich clever kombinieren indem man beispielsweise den Schlüsselaustausch mittels asymmentrischer Verschlüsselung durchführt, den eigentlichen Nachrichtenaustausch aber mit symmetrischer.

Beides auf einmal

Die beiden "Betriebsarten" von GPG (Signieren und Verschlüsseln) lassen sich auch kombinieren - dazu müssen wir einfach die jeweils passenden Argumente zusammen angeben ;)

Wie funktioniert das Web of Trust?

Das Web of Trust ist die andere grosse Komponente von GPG, die abgesehen von kryptographischen Aspekten zur Sicherheit des Gesamtsystems beiträgt. Das Web of Trust besteht aus "Bezeugungen" durch individuelle Key-Inhaber, dass ein anderer Key-Inhaber derjenige ist, der aus der Key-UID (bspw. durch Name, Foto, etc) hervorgeht. Hierzu wird normalerweise die Vorlage eines legalen Ausweisdokumentes verlangt, um die Identität gegenprüfen zu können. Danach signiert der Prüfende die UIDs am Schlüssel des zu prüfenden, was eine Bezeugung der Identität durch diesen Schlüssel darstellt. Die entstehenden Signaturen werden dann veröffentlicht, was zum namensgebenden Netz an gegenseitigen Vertrauensbezeugungen führt.

Als dritter Teilnehmer nützt mit dieses Netz insofern, als ich diesen Vertrauenspfaden folgen kann, um die Identität eines Key-Inhabers welchen ich persönlich nicht verifizieren kann (bspw. weil er auf der anderen Seite der Welt wohnt) mit relativer Sicherheit festzustellen. Möchte ich beispielsweise sicherstellen, dass ein Key D auch zu Person D gehört (was zum Beispiel zum Beginn einer asymmetrisch verschlüsselten Kommunikation wichtig ist), versuche ich einen Pfad entlang der Schlüsselsignaturen von mit bis zu meinem Ziel zu finden. Finde ich einen solchen, ist die Wahrscheinlichkeit, dass eine dritte Person diesen Schlüssel gefälscht hat, sehr gering. Finde ich keinen Pfad, heisst dies aber im Umkehrschluss nicht, dass diese Person nicht die ist, für die sie sich ausgibt. Diese Fragestellung ist eines der zentralen Probleme moderner Kommunikation.

Die meisten Teilnehmer am Web of Trust hängen an ihren Schlüssel eine Information an (bspw. über das Kommentarfeld einer UID), welche ihre Signing Policy beschreibt. Dieses Dokument spezifiziert, unter welchen Umständen und mit welchen Identitätsbeweisen sie eine Signatur zu einem Key beitragen. Da die Identität eines Kommunikationspartners (zb. in für investigative Journalisten) teils auch von lebenswichtiger Bedeutung sein kann, werden die wenigsten Teilnehmer einen Key signieren, dessen Eigentüer sie nicht kennen. Anfragen per E-Mail sind daher meist nutzlos. Eine gute Grundlage für eine Signing Policy bilden zum Beispiel
  • Eine fälschungssichere Repräsentation des Schlüssels
  • Ein gültiger Identitätsbeweis (Personalausweis, etc)
  • Persönliche Übergabe

Da die weitgehende Umgangssprache im Internet Englisch ist, sind auch die meisten Signing Policies auf Englisch verfasst. Wir haben eine Beispiel-Signing-Policy verfasst, die dazu gedacht ist, sie auf eigene Bedürfnisse anzupassen. Um aus dem Dokument beispielsweise eine HTML-Seite zu generieren, die auf einer eigenen Homepage eingebunden (und von dort als Signing-Policy auf dem Key angegeben werden kann), kann Markdown verwendet werden. Um die Gültigkeit der Policy für einen Key zu demonstrieren, empfiehlt es sich, die angepasste Policy mit dem Key für den sie gelten soll zu signieren und diese Signatur dann auch zur Verfügung zu stellen.

Einige Personen möchten selbst entscheiden, welche Signaturen für ihren Schlüssel sie veröffentlichen möchten. Aus Höflichtkeit stellt man neue Signaturen den Schlüsselinhabern daher privat zur Verfügung, statt sie ungefragt auf einem Keyserver zu veröffentlichen.

Eine gute Vorlage für eine Papier-Repräsentation eines eigenen Schlüssels erhält man beispielsweise durch das Tool gpg-key2ps. Dabei sollte man aber stets darauf achten, diese Zettel nicht aus den Augen zu lassen - jemand könnte sie gegen welche mit einem gefälschten Key austauschen.

Eine gute Gelegenheit, viele (auch gut verbundene) Signaturen für seinen Key zu bekommen stellen so genannte Key-Signing-Parties dar. Hier treffen sich mehrere Personen und tauschen untereinander Signaturen nach den beschriebenen Kriterien aus. Auch Linux-Dsitributionen und Open-Source-Projekte veranstalten oft solche Events, da ein grossteil ihrer Kommunikationsinfrastruktur auf dem Web of Trust beruht.

Signaturen abholen & anzeigen

Sollte jemand unseren Key signiert haben und die resultierende Signatur direkt auf einem Keyserver veröffentlich haben, können wir mit dem Befehl
user@box:~$ gpg --keyserver <server> --recv-keys <identifier>
den aktuellen Status unseres Keys von einem Keyserver abholen. Die Keyserver synchronisieren sich untereinander mit ein wenig Versatz, es kann also ein bisschen dauern bis die Signaturen auf unserem Lieblingskeyserver verfügbar sind. Mit diesem Befehl können wir auch beliebige Keys von anderen Personen (bspw. Personen deren Key wir selbst signieren wollen) von den Servern abrufen. Diese öffentlichen Schlüssel werden dann in unseren lokalen Keyring kopiert und sind dort auch offline verfügbar. Eine gute Übersicht über aktive Keyserver findet sich bei sks-keyservers.

Manche Key-Inhaber möchten ihre Schlüssel aus diversen Gründen nicht auf Keyservern veröffentlichen, sondern versenden bspw. auf Anfrage ihre Schlüssel als einzelne Dateien. Um diese Dateien zu importieren, verwenden wir den folgenden Befehl:
user@box:~$ gpg --import <datei.gpg>
Möglicherweise ist die Datei verschlüsselt. Sollte dies der Fall sein müssen wir sie natürlich vorher entschlüsseln.

Die aktuell in unserem Keyring vorhandenen Schlüssel werden mit folgendem Befehl angezeigt:
user@box:~$ gpg --list-keys
Analog lassen sich mit folgendem Befehl alle Signaturen an bestimmten Schlüsseln anzeigen:
user@box:~$ gpg --list-sigs <identifier>

Wie signiere ich einen Schlüssel

Prinzipiell signiert man beim Web of Trust eigentlich keine ganzen Schlüssel (wohl aber mit einem Schlüssel), sondern einzelne UIDs. Dabei existieren verschiedene "Vertrauensgrade", welche optional verwendet werden können um bspw. die Sorgfalt der Verifikation zu zeigen. Die individuelle Bedeutung der Levels wird oft in der Signing Policy genauer beschrieben, die Beispielangaben durch GPG sind:
  • Level 0 Keine Aussage. Dies ist der Standard wenn die Angabe von Vertrauensgraden nicht aktiviert ist. Kann auch sonst beispielsweise für pseudonyme Keys verwendet werden.
  • Level 1 Keine Identitätsprüfung vorgenommen, aber wir glauben dass der Key dem Benutzer gehört. Die meisten Teilnehmer am Web of Trust raten von der Verwendung dieses Levels ab.
  • Level 2 Grundlegende Identitätsüberprüfung, bspw durch Vergleich des Fotos einer UID und Verifikation des Key-Fingerprints.
  • Level 3 Intensive Identitätsüberprüfung, bspw durch persönliche Verifikation mit Ausweisdokumenten, etc.
Um einen Schlüssel zu signieren, müssen wir ihn erst einmal, wie oben beschrieben, importieren (bspw von einem Keyserver oder aus einer Datei). Signiert wird immer mit dem private-Teil des Master-Keys, also benötigen wir diesen auf der Maschine, auf der wir die Signatur machen wollen.

Um nun die eigentliche Signatur vorzunehmen, starten wir die Bearbeitung des zu signierenden Keys mit
user@box:~$ gpg --ask-cert-level --edit-key <identifier>
Die Option --ask-cert-level aktiviert dabei die detaillierte Abfrage des Vertrauensgrades. Danach selektieren wir die UID, welche wir signieren wollen und starten den Signatur-Assistenten mit
gpg> uid <nummer>
gpg> sign

Nachdem der Assistent seine Abfragen beendet hat, kann man den Prozess für andere UIDs wiederholen, oder den Key mit der neuen Signatur mittels save in den lokalen Keyring speichern.

Alternativ können mit folgendem Befehl alle UIDs auf einmal signiert werden:
user@box:~$ gpg --ask-cert-level --sign-key <identifier>

Schlüssel und Signaturen veröffentlichen

Um die Informationen und Signaturen aus dem lokalen Keyring an einen Keyserver zu übertragen, wird folgender Befehl verwendet:
user@box:~$ gpg --keyserver <keyserver> --send-keys <identifier>
Es ist dabei nicht nötig, den Key an mehrere Keyserver zu übertragen, da diese sich untereinander synchronisieren. Aus Höflichkeit sollte darauf geachtet werden, dass nicht jeder begeistert ist, ungefragt neue Signaturen an seinem Key auf den Keyservern zu finden. Prinzipiell ist ein gutes vorgehen, neue Signaturen an den Keys anderer einzeln zu exportieren und diese ihnen dann, sinnvollerweise in verschlüsselter Form, zukommen zu lassen. Dies lässt ihnen die Option, selbst zu entscheiden welche Signaturen sie veröffentlichen. Ausserdem ist das hochladen der Signaturen dann ein weiterer Beweis dafür, dass der Empfänger diesen Key und die dazugehörigen UIDs auch kontrolliert und abruft.

Der Prozess, eine einzelne Signatur zu exportieren, wird bei GPG leider sehr erschwert. Prinzipiell muessen dafür folgende Schritte durchgeführt werden:

  1. Importieren des Keys aus beliebiger Quelle
    Dabei werden auch bisherige Signaturen am Key mit importiert.
  2. Minimieren des Keys
    Hierbei werden die bisher existierenden Signaturen des Keys vom lokalen Keyring gelöscht. Dazu öffnet man den zu bearbeitenden Schlüssel mittels
    user@box:~$ gpg --edit-key <identifier>
    und gibt dann nacheinander die Befehle minimize und save ein.
  3. Signieren einer (oder aller) UIDs des Keys
    Siehe vorherige Sektion.
  4. Exportieren des Keys Nach dem signieren kann der Schlüssel aus dem lokalen Keyring mittels folgendem Befehl in eine Datei exportiert werden:
    user@box:~$ gpg --export --armor <identifier> > <dateiname>
    Idealerweise verschlüsselt man diese Datei dann auch noch an den Eigentümer des Keys mittels:
    user@box:~$ gpg --armor --encrypt --recipient <identifier> <dateiname>

    Sollen die Signaturen einzelner UIDs in einzelne Dateien exportiert werden, muss nach dem Signieren einer UID und dem Export dieser Signatur der Key nochmals minimiert (also die gerade gemachte Signatur entfernt) werden.

Dieser Prozess kann durch automatisierte Tools vereinfacht werden, näheres dazu findet sich in einer späteren Sektion.

Signaturen importieren

Sollten wir von einem anderen Benutzer eine Email mit einer neuen Signatur für unseren Schlüssel bekommen haben, können wir diese mit demselben Import-Befehl den wir für ganze Keys benutzen importieren:
user@box:~$ gpg --import <datei.gpg>
Dies liegt daran, dass jede Einzel-Signatur prinzipiell eine Kopie des Öffentlichen Schlüssels mit genau dieser einen Signatur ist. Beim importieren fügt GPG dann die Information aus der Datei mit den im lokalen Keyring vorhandenen Signaturen zusammen. Dies geschieht allerdings erst einmal nur lokal, wir müssen die neue Signatur danach also noch wie in der vorherigen Sektion beschrieben veröffentlichen.

Automatisierung

Wie man merkt, sind die diversen Prozesse des Web of Trust eigentlich immer dieselbe Abfolge. Daher gibt es mehrere Tools, die diesen Prozess auf mehr oder weniger aufwändige Weise automatisieren. Für Personen, die Erfahrung mit der Administration von Linux-Systemen haben und bspw. einen lokalen Mailausgangsserver betreiben, bietet sich caff an, welches die resultierenden Signaturen gleich verschlüsselt via Email an die Empfänger übermittelt. Auf airgapped-Maschinen möchte man natürlich möglichst wenig externen Code ausführen, um die Angriffsfläche zu minimieren. Hier gibt es beispielsweise signet, welches ähnliche Funktionalitäten wie caff bietet, aber in bash geschrieben und auf Offline-Systeme ausgerichtet ist.

Was tun, wenn der Schlüssel kompromittiert wurde?

Sollte einer der gerätespezifischen Schlüssel kompromittiert werden (Malware auf dem Handy, etc) oder verloren gehen, so laden wir zuerst wieder unser gesichertes System und mounten das sichere Speichermedium.
Dann führen wir nacheinander folgende Schritte aus:
  1. GNUPGHOME wieder auf das "sichere" GPG-Verzeichnis setzen.
    user@box:~$ export GNUPGHOME=/media/meinSicheresMedium/gpg_home
  2. Schlüssel bearbeiten.
    user@box:~$ gpg --edit-key <identifier>
  3. Mit
    gpg> key <keyindex>
    die Subkeys auswählen, die revoked werden sollen. keyindex ist dabei der Index des Unterschlüssels, beginnend bei 1. Ein key-Befehl selektiert einen Schlüssel (bezeichnet durch sub*), ein weiterer deselektiert ihn.
  4. gpg> revkey
    startet einen Assistenten, der einen Grund für den Rückruf sowie die Passphrase abfragt.
  5. gpg> save
    speichert unsere Änderungen.
  6. Wir exportieren jetzt noch unseren öffentlichen Schlüssel neu, um die Veränderung bekannt machen zu können.
    user@box:~$ gpg --export --armor --no-emit-version <identifier> > /media/unsichererTeil/mein-key.asc
  7. Jetzt können wir den öffentlichen Schlüssel auf einer "unsicheren" Maschine wieder importieren und an die Keyserver senden.
    user@box:~$ gpg --import /media/unsichererTeil/mein-key.asc
    user@box:~$ gpg --send-keys <identifier>
Um neue Subkeys hinzuzufügen, können wir der obigen Anleitung zum generieren des Keypairs folgen und dabei die Schritte 2 und 3 auslassen.

Sollte dagegen das Master-Keypair verloren gegangen sein oder uns versehentlich in irgendwelche unsicheren Medien gekommen sein, wird es Zeit, das Revocation Certificate abzustauben. Wenn wir die damals erzeugte Datei noch verfügbar haben, ist der Schritt recht einfach:
user@box:~$ gpg --import /media/meinSicheresMedium/master-pair.revcert
Sollte dies nicht mehr der Fall sein, müssen wir die ausgedruckte Version rauskramen, abtippen und dann genauso importieren. Der Import des Revocation Certificates markiert das komplette Keypair als revoked. Um das nun auch noch der Welt mitzuteilen, sollten wir die Keyserver von der Veränderung in Kenntnis setzen:
user@box:~$ gpg --send-keys <identifier>
Mit dem nächsten Update unseres Keys aus den Keyservern sind damit die Benutzer in Kenntnis gesetzt, dass der Key zurückgerufen wurde. Jetzt schnell ein neues Keypair erzeugen! ;)

Weiterführendes & Links

Sollte euch eines der genannten Projekte sehr gut gefallen, würden sie sich alle über Spenden (ob nun Geld oder Manpower beim Bugs reporten, Bugs fixen oder User supporten) oder Lob freuen! Denkt dran, nur weil Software kostenlos ist, ist sie noch lange nicht wertlos! Die Informationen in diesem Dokument wurden zum grossen Teil aus dem Kopf geschrieben - unterstützt durch die Dokumentationen der verschiedenen Projekte und einige Blogeinträge und Mailinglisten-Posts, für die wir den Autoren sehr dankbar sind:
kopimi wtfpl