zurück zur Startseite

Einführung in die Funktionsweise von OpenPGP / GnuPG

Version 1.0.1, 23.07.2010

  1. historische Entwicklung

  2. technische Basis

  3. die wichtigsten Aktionen

    1. Erzeugung eines Schlüsselpaars

    2. Schlüssel beglaubigen

    3. Verschlüsseln

    4. Signieren

    5. Authentifizieren

  4. Smartcards

Erläuterung zum Inhalt dieser Seite

Im folgenden werden viele Möglichkeiten erläutert, wie man mit gpg arbeiten kann. Unerfahrene Nutzer sollten sich nicht vom Umfang und dem technischen Tiefgang abschrecken lassen. Man muss diese Seite nicht verstanden haben, um gpg nutzen zu können. Ich halte es aber für einen guten Überblick der Technologie, sich das hier einmal durchzulesen. An vielen Stellen wird man für sich entscheiden, dass man das jeweilige Feature nicht braucht, aber dann hat man mal davon gehört und ist zudem mit einigen wichtigen Aspekten des Umgangs mit Kryptografie konfrontiert worden.

historische Entwicklung

1991 veröffentlichte der amerikanische Programmierer Phil Zimmermann seine Software Pretty Good Privacy (PGP). Sie wurde von seiner Firma kommerziell vertrieben, war aber für Privatanwender kostenlos nutzbar. Als Alternative wurde 1998 der OpenPGP-Standard verabschiedet und in der FOS-Software GnuPG (Gnu Privacy Guard) implementiert. GnuPG ist die dominante (wenn nicht sogar einzige) Basis für freie und offene OpenPGP-Software.

technische Basis

GnuPG bzw. gpg/gpg2 (der technische Programmname) ist ein Konsolen-Programm und deshalb aus Sicht der meisten Anwender nicht benutzerfreundlich. Es gibt allerdings einige Programme, die als grafische Oberfläche für gpg fungieren, so dass man sich meist nicht mit dem Eintippen von Befehlen auseinandersetzen muss, sondern die gewünschten Aktionen intuitiv mit der Maus oder einem Menü vornehmen kann. Viele sehr spezielle Funktionen werden allerdings von den grafischen Programmen nicht angeboten. In solchen Fällen muss man gpg direkt aufrufen (in der Konsole/Shell), um das Gewünschte zu erreichen.

Man kann über eine gpg-Konfigurationsdatei (unter Linux: ~/.gnupg/options) das Standardverhalten von gpg und Programmen, die es aufrufen, beeinflussen.

gpg kann inzwischen nicht mehr nur OpenPGP verwenden, sondern auch das zweite relevante Kryptografieverfahren, S/MIME. Es wird auch von dem grafischen Programm Kleopatra unterstützt, das sowohl für Windows als auch für Linux (usw.) zur Verfügung steht.

Installation

Man kann gpg direkt von der GnuPG-Webseite herunterladen. Das ist aber zumeist nicht der beste Weg (Ausnahme: frühe Updates unter Windows).

Unter Linux u.Ä. sollte gpg sowieso installiert sein, alleine schon für die Prüfung der Integrität von Updates. Wohl jede Distribution bietet die Installation und Updates für gpg an.

Für Windows-Anwender ist es am einfachsten, das kostenlose Programm gpg4win zu installieren. Dies ist ein grafisches Installationsprogramm, das gpg und einige (grafische) Zusatzprogramme (Schlüsselverwaltung; Integration in den Windows-Dateimanager) beinhaltet. Außerdem gibt es eine deutsches Onlinehilfe.

die wichtigsten Aktionen

Erzeugung eines Schlüsselpaars

Viele OpenPGP-Programme bieten zunächst die Erzeugung eines Schlüsselpaars an, wenn sie beim Start feststellen, dass es noch keins gibt. Die Erzeugung eines Schlüssels ist nichts anderes als die Bestimmung einer geeigneten, sehr großen Zufallszahl. Darin liegt ein erhebliches Problem (Sicherheitsrisiko), weil Computer eben nicht dafür geschaffen sind, zufällige Ergebnisse zu produzieren, sondern ganz im Gegenteil deterministisch arbeiten. Computer sind grundsätzlich schlechte Zufallszahlengeneratoren. Nur wenige Computer verfügen über entsprechende Zusatzhardware, die dieses Problem beseitigt. Für kleine Zufallszahlen sind Computer brauchbar. Leider hängt die Sicherheit von Kryptografie direkt von der Länge der verwendeten Schlüsselzahlen ab. Für normale Anwendungsfälle kann man dieses Problem ignorieren, aber wenn man wirkliche Sicherheit braucht und/oder z.B. sehr viele Verschlüsselungen in kurzer Zeit auf einem Rechner durchführt, sollte man sich darüber im Klaren sein, dass ein Programm wie gpg niemals mehr Sicherheit liefern kann als der Computer Entropie ("Zufälligkeit").

Primärschlüssel

Aus bestimmten technischen Gründen, auf die hier nicht eingegangen wird, bestehen OpenPGP-Schlüssel normalerweise aus mehr als einem Schlüssel, typischerweise aus zweien. Der Primärschlüssel ist, man ahnt es schon, der wichtigste. Seine Wichtigkeit resultiert daraus, dass er zwingend in der Lage sein muss und als einziger in der Lage ist, andere Schlüssel (vor allem die eigenen Unterschlüssel) und außerdem Benutzerkennungen zu unterschreiben. Wenn ein OpenPGP-Schlüssel in seiner Gesamtheit identifiziert wird ("der Schlüssel für die E-Mail-Adresse oder Person XY"), bezieht sich dies immer auf den Primärschlüssel.

Die gängigen Algorithmen für einen Primärschlüssel sind RSA und DSA. Für normale Zwecke bestehen keine relevanten Unterschiede zwischen den beiden Verfahren.

Die gängige Struktur eines OpenPGP-Schlüssels sieht so aus, dass er einen RSA- oder DSA-Primärschlüssel hat, der Daten (S) und andere Schlüssel (C; nur diese Fähigkeit ist ganz allgemein zwingend) signieren kann (bzw. darf) und eventuell auch zur Authentifizierung (A) verwendet werden kann und der einen Elgamal-Unterschlüssel zum Verschlüsseln (E) hat.

externe Speicherung des Primärschlüssels

Es ist sinnvoll, einen Schlüssel so zu erzeugen, dass der Primärschlüssel nur zertifizieren (d.h. eigene Unterschlüssel und andere Hauptschlüssel signieren) kann, und diesen nicht auf einem normalen Arbeitsrechner zu speichern. Die Motivation dafür und die Vorgehensweise sind hier erklärt.

Schlüssellänge

Für alle Schlüssel muss die gewünschte Länge angegeben werden. Meist sind dies 1024, 2048 oder 4096 Bit. Für normale Anwendungen reicht 1024 Bit aus. Die Erzeugung eines 2048-Bit-Schlüssels dauert schon merklich lange (ganz abgesehen von dem o.g. Problem, dass normale Rechner gar nicht so viel Entropie besitzen, so dass man am Ende viel scheinbare Sicherheit hat). Bei einem 4096-Bit-Schlüssel dauert nicht nur die Erzeugung ewig, sondern auf langsamen Rechnern auch die Entschlüsselung von Nachrichten lange.

Gültigkeitszeitraum

Man kann (mit dem Konsolen-gpg auch getrennt für Primär- und Unterschlüssel) die maximale Gültigkeit des Schlüssels festlegen. Nach dem Zieldatum verweigern normale Programme die Verwendung des Schlüssels. Eine endliche Lebensdauer verhindert, dass versehentlich uralte Schlüssel verwendet werden, die vom Eigentümer gar nicht mehr benutzt werden und vielleicht schon kompromittiert sind. Eine kurze Gültigkeit des Primärschlüssels bringt allerdings das Problem mit sich, dass nach entsprechend kurzer Zeit alle Verwender des Schlüssels den Nachfolgeschlüssel erhalten müssen. Wenn dies nicht gelingt, bevor die Gültigkeit abläuft, ist dies mit erneutem Authentifizierungsaufwand verbunden.

Sinnvoller ist eine Beschränkung des Gültigkeitszeitraums für Verschlüsselungs-Unterschlüssel. Wenn nur diese ungültig werden, können die Verwender des eigenen Schlüssels sich mit wenig Aufwand den Nachfolgeschlüssel beschaffen. Verschlüsselungsschlüssel sind eher Angriffen ausgesetzt als Signaturschlüssel. Je mehr verschlüsselte Daten dem Angreifer zur Verfügung stehen, desto besser für ihn. Deshalb mag es sinnvoll sein, sich jährlich einen neuen Verschlüsselungs-Unterschlüssel zu erzeugen. Aber auch das ist ein eher theoretisches Problem, das man für die erste Beschäftigung mit gpg getrost ignorieren kann. Auch wenn man die Gültigkeit des ersten Unterschlüssels nicht begrenzt, kann man später einen Nachfolgeschlüssel erzeugen.

Unterschlüssel

Es können beliebig viele Unterschlüssel angelegt werden, deren Algorithmus (DSA/RSA/Elgamal), Länge und Fähigkeiten (S/A/E) nichts mit dem Primärschlüssel zu tun haben, allerdings begrenzt der Algorithmus des Unterschlüssels dessen Länge und Fähigkeiten (so kann beispielsweise Elgamal nur verschlüsseln).

Ein abschreckendes Beispiel:

start cmd:> gpg --list-keys 71FDC5CB
pub   1024D/71FDC5CB 2010-02-25 [verfällt: 2011-02-25]
uid                  Test Key (Demo) <test@key.inv>
sub   1024D/DE57F59A 2010-02-25 [verfällt: 2010-12-22]
sub   1024R/BB8A54D2 2010-02-25 [verfällt: 2011-01-21]
sub    512g/801FDB58 2010-02-25 [verfällt: 2010-12-22]
sub   1024R/7D2C11A4 2010-02-25 [verfällt: 2011-01-21]
sub   1024D/1C0A9017 2010-02-25 [verfällt: 2012-02-25]
sub   1024R/027DBA86 2010-02-25 [verfällt: 2013-02-24]

Angezeigt werden Länge (1024 Bit), Typ (DSA), (short) ID (71FDC5CB), Erzeugungs- und Verfallsdatum des Primärschlüssels sowie von sechs unterschiedlichen Unterschlüsseln sowie die einzige UID dieses Schlüssels. Warum es so viele Unterschlüssel sind, zeigt sich bei einem anderen gpg-Aufruf:

start cmd:> gpg --expert --edit-key 71FDC5CB
Geheimer Schlüssel ist vorhanden.

pub  1024D/71FDC5CB  erzeugt: 2010-02-25  verfällt: 2011-02-25  Aufruf: C
                     Vertrauen: uneingeschränkt Gültigkeit: uneingeschränkt
sub  1024D/DE57F59A  erzeugt: 2010-02-25  verfällt: 2010-12-22  Aufruf: S
sub  1024R/BB8A54D2  erzeugt: 2010-02-25  verfällt: 2011-01-21  Aufruf: S
sub   512g/801FDB58  erzeugt: 2010-02-25  verfällt: 2010-12-22  Aufruf: E
sub  1024R/7D2C11A4  erzeugt: 2010-02-25  verfällt: 2011-01-21  Aufruf: E
sub  1024D/1C0A9017  erzeugt: 2010-02-25  verfällt: 2012-02-25  Aufruf: A
sub  1024R/027DBA86  erzeugt: 2010-02-25  verfällt: 2013-02-24  Aufruf: A
[ uneing.] (1). Test Key (Demo) <test@key.inv>

Jeweils zwei Unterschlüssel können Daten signieren, verschlüsseln/entschlüsseln oder authentifizieren. Der Primärschlüssel kann als einziger beglaubigen (C) und auch nur das.

Es folgt die Anzeige der Signaturen:

start cmd:> gpg --list-sigs 71FDC5CB
pub   1024D/71FDC5CB 2010-02-25 [verfällt: 2011-02-25]
uid                  Test Key (Demo) <test@key.inv>
sig 3        71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>
sig 3        ECCB5814 2010-02-25  Hauke Laging <hauke@laging.de>
sub   1024D/DE57F59A 2010-02-25 [verfällt: 2010-12-22]
sig          71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>
sub   1024R/BB8A54D2 2010-02-25 [verfällt: 2011-01-21]
sig          71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>
sub    512g/801FDB58 2010-02-25 [verfällt: 2010-12-22]
sig          71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>
sub   1024R/7D2C11A4 2010-02-25 [verfällt: 2011-01-21]
sig          71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>
sub   1024D/1C0A9017 2010-02-25 [verfällt: 2012-02-25]
sig          71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>
sub   1024R/027DBA86 2010-02-25 [verfällt: 2013-02-24]
sig          71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>

Man sieht, dass die UID und alle Unterschlüssel vom Primärschlüssel beglaubigt sind und dass andere Schlüssel (hier: ECCB5814) nur UIDs beglaubigen. Die 3 hinter sig gibt an, dass die beglaubigende Person die beglaubigte Identität sehr sorgfältig geprüft hat. 2 würde bedeuten, dass er ihn flüchtig geprüft hat, 1, dass er ihn gar nicht geprüft hat, und 0 bzw. keine Anzeige bedeutet, dass die beglaubigende Person keine Angabe dazu macht, wie sorgfältig sie war.

Benutzerkennung

Zu einem Primärschlüssel gehört mindestens eine Benutzerkennung. Diese besteht typischerweise aus dem Namen, der E-Mail-Adresse und eventuell einem Kommentar. Man kann nach belieben UIDs hinzufügen und löschen, allerdings muss immer eine erhalten bleiben. So kann man denselben Schlüssel für mehrere E-Mail-Adressen verwenden: Man trägt einfach alle E-Mail-Adressen als UIDs ein. Das ist bequem und nur dann problematisch, wenn nicht jeder wissen soll, dass alle Adressen zu derselben Person gehören.

start cmd:> gpg --list-sigs 71FDC5CB
pub   1024D/71FDC5CB 2010-02-25 [verfällt: 2011-02-25]
uid                  Test Key (Demo) <test@key.inv>
sig 3        71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>
sig 3        ECCB5814 2010-02-25  Hauke Laging <hauke@laging.de>
uid                  Neue UID (nach der Signierung hinzugefügt) <test2@key.inv>
sig 3        71FDC5CB 2010-02-25  Test Key (Demo) <test@key.inv>

Zu der ersten UID Test Key (Demo) <test@key.inv> ist nun die UID Neue UID (nach der Signierung hinzugefügt) <test2@key.inv> hinzugekommen. Da dies nach der Signierung durch den anderen Schlüssel ECCB5814 erfolgte, hat nur die alte UID eine Signatur von ECCB5814.

Wenn man alle UIDs löscht, die ein Kommunikationspartner signiert hat (oder über das web of trust verifizieren kann), dann ist der Schlüssel für ihn wertlos.

Die hier angezeigten Informationen finden sich (fast alle) auch in der Schlüsselübersicht der grafischen Programme. Diese Zusammenhänge muss man verstehen:

  1. Ein Schlüssel wird über seinen öffentlichen Primärschlüssel identifiziert (bzw. über (den letzten Teil) dessen Fingerabdruck).

  2. Zu einem Primärschlüssel gehören eine oder mehrere UIDs (Name, E-Mail).

  3. Alle UIDs und alle Unterschlüssel sind von dem Primärschlüssel unterschrieben. Eine UID oder ein Unterschlüssel ohne Signatur (so was kann man regulär gar nicht erzeugen) ist wertlos bzw. sogar ein Hinweis auf Manipulation.

  4. Signaturen von anderen Schlüsseln betreffen immer nur UIDs.

  5. Jeder Primär- und Unterschlüssel besteht aus einem öffentlichen und einem privaten Schlüssel. Mit dieser Unterscheidung hat man aber nur selten zu tun, etwa dann, wenn man seine privaten Schlüssel sichern oder auf einem anderen Rechner verfügbar machen will und sie deshalb exportieren muss. gpg verwendet immer automatisch den richtigen der beiden Schlüssel.

Passphrase

Bei der Erzeugung eines Schlüssels wird man nach einer Passphrase gefragt. Diese Bezeichnung anstelle von Passwort soll zum Ausdruck bringen, dass die Eingabe auch Leerzeichen enthalten darf, also aus mehreren Wörtern, etwa einem Satz, bestehen kann. Der Sinn einer Passphrase ist zu verhindern, dass jemand, der die Datei, die den geheimen Schlüssel enthält, in seinen Besitz bringt, den Schlüssel sofort verwenden kann. Die Sicherheit einer Passphrase kann üblicherweise nicht mal im Ansatz mit der Sicherheit von OpenPGP-Schlüsseln mithalten. Eine normale Passphrase ist schnell geknackt. Man sollte also (jedenfalls bei "wertvollen" Schlüsseln) eine lange Zufallsfolge wählen (was man sich eben gerade noch so merken kann). Für selten genutzte Schlüssel kann man auch eine lange Passphrase wählen, die man sich aufschreiben muss.

Schlüssel beglaubigen

Es ist sehr wichtig zu verstehen, warum Schlüssel signiert werden. Technik löst zumeist nicht von allein alle Probleme des Anwenders. Sie bietet ihm lediglich die Möglichkeit dazu. Um sein Problem zu lösen (und nicht noch zu vergrößern) muss der Anwender die Technik aber noch richtig einsetzen!

Die Motivation dafür, Verschlüsselung zu benutzen, ist typischerweise die, dass nur der beabsichtigte Empfänger die Nachricht lesen kann. Das erreicht man, indem man die Nachricht mit seinem Schlüssel verschlüsselt. Das muss aber auch wirklich der korrekte Schlüssel sein, den sonst wäre ein Dritter in der Lage, die Nachticht zu lesen. Wenn man einen Schlüssel aus einer unsicheren Quelle hat (von einem Schlüsselserver, von einer Webseite, aus einer E-Mail), dann kann der manipuliert sein. Man will etwas an Person A schicken, und Person B ist in der Lage, die Daten zu manipulieren, die man bekommt (durch Manipulation der Verbindung oder der Daten am Ziel). Dann kann B den Schlüssel von A gegen den eigenen austauschen. Man verschlüsselt also unwissentlich an B, der fängt die Nachricht ab, packt sie aus, packt sie für A mit dessen richtigem Schlüssel ein, und weder man selber noch der Empfänger hat eine Chance, die Manipulation zu erkennen. Das nennt man einen Man-in-the-middle-Angriff.

Deshalb ist es ungemein wichtig, dass man die Zuordnung von Schlüsseln zu einer Person oder Organisation gegen Fehler absichert. Das geschieht, indem man sich den Schlüssel oder seinen Fingerabdruck aus einer sicheren Quelle beschafft, oder mit Hilfe einer indirekten Bestätigung. Die gängigsten Möglichkeiten der Überprüfung sind, dass man den Fingerabdruck schriftlich (nichtelektronisch, am besten persönlich) oder telefonisch erhält. Man vergleicht ihn mit dem Fingerabdruck des Schlüssels, den man importiert hat. Wenn der Fingerabdruck stimmt, stimmt auch der Schlüssel.

Indirekte Überprüfung funktioniert so: Man will den Schlüssel von A überprüfen; den von B hat man erfolgreich überprüft. Wenn B den Schlüssel von A signiert hat und man dieser Signatur vertraut (also darauf vertraut, dass B den Schlüssel ordentlich überprüft hat), kann der Schlüssel als überprüft gelten. Wenn man der Überprüfung durch B nur begrenzt vertraut, mag man zufrieden sein, wenn nicht nur B, sondern auch C und D den Schlüssel signiert haben. Das ist keine technische Entscheidung, sondern ein organisatorisches bzw. soziales Problem. Je mehr Signaturen ein Schlüssel hat, desto besser. Bei mehr Signaturen ist die Wahrscheinlichkeit größer, dass ein Benutzer des Schlüssels wenigstens einer davon vertraut, ebenso die, dass er mehrere bekannte Signaturen findet und dem Schlüssel dadurch stärker vertrauen kann.

Anzeige des Fingerabdrucks

start cmd:>gpg --fingerprint 71FDC5CB
pub   1024D/71FDC5CB 2010-02-25 [verfällt: 2011-02-25]
  Schl.-Fingerabdruck = A92E 91A9 5526 AB4C 7B80  3B11 E47D A993 71FD C5CB

Relevant ist üblicherweise nur der Fingerabdruck des Primärschlüssels. Es handelt sich dabei um einen SHA-1-Hash; die 40 Zeichen entsprechen einer Hashlänge von 160 Bit (10^48). Die letzten acht Zeichen ergeben die short ID des Schlüssels, die letzten 16 die long ID.

Zusatzangaben zur Signatur

Man kann allerlei ergänzende Angaben machen, wenn man einen Schlüssel signiert. Die häufigste dürfte sein, wie gründlich man den Schlüssel geprüft hat. Möglich sind die Angaben 0 (keine Angabe), 1 (keine Prüfung), 2 (flüchtige Prüfung) und 3 (sehr sorgfältige Prüfung). Das Ergebnis indirekter Prüfungen kann man davon abhängig machen, was die anderen diesbezüglich angegeben haben. Man kann auch die Gültigkeit der Signatur zeitlich begrenzen und eine URL hinzufügen (mit --cert-policy-url URL, sinnvollerweise in der Konfigurationsdatei), unter der man Angaben dazu macht, wie man Schlüssel prüft, bevor man sie selber signiert, damit Dritte sich ein besseres Bild davon machen können, welchen Wert die eigenen Signaturen haben.

Signatur erzeugen

Für das Erzeugen einer Signatur benötigt man den eigenen privaten Schlüssel, wird also nach der Passphrase gefragt.

start cmd:> gpg --local-user ECCB5814 --ask-cert-level --ask-cert-expire --edit-key 71FDC5CB
[...]

Man muss als Kommando im Menü, das --edit-key erzeugt, das Kommando sign eingeben. Für Spezialfälle gibt es Variationen: lsign, tsign, nrsign. --local-user ECCB5814 gibt an, welcher eigene Schlüssel verwendet werden soll, um die Signatur zu erzeugen. Man kann in der Konfigurationsdatei allerdings einen Standardschlüssel definieren. Durch die Optionen --ask-cert-level und --ask-cert-expire wird man nach dem Prüfungsablauf und der Gültigkeitsdauer der Signatur gefragt. Wenn man das nicht benötigt, lässt man sie weg. Manche grafischen Oberflächen für gpg fragen das entweder nicht ab oder tragen die Antwort nicht in die Signatur ein. In dem Fall bleibt einem dann womöglich nur der Weg über die Kommandozeile.

Verschlüsseln

Zumeist verschlüsselt man E-Mails; das erledigt dann der Mailclient für einen; mit gpg hat man da nicht zu tun. Man wählt ggf. aus, dass diese Mail verschlüsselt werden soll, eventuell noch den zu verwendenden Schlüssel (den der Mailclient typischerweise anhand der Empfängeradresse(n) auswählt, und das war’s auch schon. Bei guten Mailprogrammen kann man für den Body der Mail und alle Attachments einzeln angeben, ob der jeweilige Teil verschlüsselt werden soll.

Neben E-Mails kann man aber auch Dateien und sonstige Datenströme (z.B. Text) verschlüsseln. Dabei kann man eine Reihe interessanter Optionen nutzen. Neben der üblichen, asymmetrischen Verschlüsselung (mit dem öffentlichen Schlüssel des Empfängers) kann man Daten auch mit einem Passwort verschlüsseln ("symmetrisch") und sogar beides zusammen:

start cmd:> gpg --encrypt --symmetric --recipient 71FDC5CB testdatei.txt
[...]

Dieser Aufruf fragt die Verschlüsselungspassphrase ab und erzeugt eine Datei testdatei.txt.gpg, die man sowohl alleine mit der Passphrase als auch alleine mit dem privaten Schlüssel von 71FDC5CB entschlüsseln kann. Durch mehrfache Verwendung von --recipient kann die Datei für mehrere Empfänger verschlüsselt werden (sie wird dadurch kaum größer, siehe Abschnitt technische Details). Es ist oftmals sinnvoll, eine Nachricht auch für sich selber zu verschlüsseln. Das kann man in der Konfigurationsdatei mit den Optionen encrypt-to und hidden-encrypt-to und der Angabe der eigenen Schlüssel-ID einstellen. Für einen einzelnen Aufruf nimmt man ganz normal --recipient.

Die Option --armor sorgt dafür, dass die verschlüsselte Datei (fast) nur auch alphanumerischen Zeichen besteht. So kann man verschlüsselte Daten auch über Medien transportieren, die dafür nicht gedacht sind, etwa Chatprogramme oder Webseiten:

echo "$kompromittierende_aussage" | gpg --armor --encrypt --sign

-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.15 (GNU/Linux)

hQEMA44903pRsnn6AQgAsac1BympF9+mLFGKshbWWawVKQucT+8LSHejFBdd5Tco
tN6Om3/e8gDXaze+CocMJ8/S5Seli1s6a5aamW2J+QW8w4kMU87+cdfGTQ3QRoge
6r08rCMzAYLq8AcO/fegpDVm6wTl9WPnjmNmEFcTeshVbFzxUbsaIFtFciD/nopV
GDhZW6111V+TafAHkvpwdwxFMMLIQpl/xe06wZTip/zJWVCSSpnYupQ4OzsFABvL
9GFGBXegXKTOBKcGpywO6hO9t51Q6JLuK+Gug/2Sd2D9G2kuWep+cnRX4D7KGa3n
P57XYzzk+Fk3JXug33aed8Nj19DnAUkS9TKm2+3fotLBAwH8TzR/jn914jkb7tfj
AfS3J/UIb7Q9Yr53BBQlR1v1LV8xpeYxlBNoFbD1XHrj0Iucpru6seTmxZJjnhml
l60DEFqt0RPwWIoApmZo5hgicwJHJP/JsNTU2tDjfxGc2uUnuHpr9Yg0D/KjO6+z
/fKTY/WK0OJ0fGq2h36LOY0/H8KQ7bo2VoyPuOxZGZ/WVYLtPSP3aX7oPELWsGeP
yQRELtCqN/ak/yvTONwUCaXm+Np+Zj+jX3SgcUPNHb9OHfQ9YnPIcd/WvVhUuKWz
a6TqRR+3LtgCkdMl37Aif2p5zcQYIgz3BIh153Cfm9oLQueseZWW/BIjWXqqHR9h
p6B8YE2ULnEsLtrjRd/nN11dBNQLW5mX5/a/Cae3in8cGnU9Jni1BIJbYLDJDGKM
wXy0COhvISRJ7Req81eUgapgHbEjeIheMhImLP3lOdTBJXx7B/isOEcOfyWBwUO0
6+vv6zxWMTB0TuUxMDPCgYjZyPFIuw4C0yJ1AcE49lg2Vj1J4yw0gZzDMdepBwDj
+D4PT7djKGrGTKkP+24Od/0TkSayH6NVCEv6+ia5aSwZIFHSvFah6iP73NxQuFic
HGvGAgI=
=GKpQ
-----END PGP MESSAGE-----

Ganz heikel, aber das sollte außer mir niemand lesen können... ;-)

technische Details

Es wird nicht die ganze Nachricht asymmetrisch verschlüsselt; das wäre viel zu aufwendig. Für jede Nachricht wird ein zufälliger Schlüssel ermittelt, mit dem die Nachricht symmetrisch verschlüsselt wird. Nur dieser Einmalschlüssel wird asymmetrisch verschlüsselt. Deshalb kann man eine Nachricht auch mehrfach verschlüsseln: Der Zufallsschlüssel wird für jeden Empfänger verschlüsselt, und alle diese verschlüsselten Varianten werden in die Containerdatei geschrieben.

start cmd:> gpg --encrypt --cipher-algo AES192 --recipient 71FDC5CB --output test.html.AES192.gpg test.html

start cmd:> gpg --encrypt --cipher-algo AES256 --recipient 71FDC5CB --output test.html.AES256.gpg test.html

start cmd:> gpg --decrypt --show-session-key --output /dev/null test.html.AES192.gpg
[...]
gpg: session key: `8:6B56B66C5765209B279FA95ED23485BF22A4CF84082A7132'

start cmd:> gpg --decrypt --show-session-key --output /dev/null test.html.AES256.gpg
[...]
gpg: session key: `9:7E4C85F5D7805467FA2D05B4CECC9BD11144E20A836AE9BFA6416AAFD689461C'

Hier wurde die Datei test.html mit zwei unterschiedlichen Algorithmen (die unterschiedlich lange Schlüssel verwenden) verschlüsselt. Beim Entschlüsseln mit der Option --show-session-key wird der symmetrische Schlüssel angezeigt. Wegen der unterschiedlichen Algorithmen sind die beiden Zufallsschlüssel unterschiedlich lang. Das --output /dev/null sorgt dafür, dass die zum Testen uninteressanten Ausgabedaten weggeworfen werden (nicht über einen gpg-, sondern einen Linux-Mechanismus).

versteckte Empfänger

Wenn man nicht möchte, dass ersichtlich ist, für wen (also für welchen Schlüssel) Daten verschlüsselt wurden, kann man sich der Optionen --hidden-recipient (zur Verschleierung einzelner Empfänger) und --throw-keyids (aller Empfänger) bedienen. Der Empfänger muss dann alle seine geheimen Schlüssel ausprobieren (das macht gpg automatisch). automatisch).

gpg schreibt zwar nur die ID des Empfängerschlüssels in den Header der verschlüsselten Nachricht, es ist aber oftmals möglich, (z.B. über Keyserver) herauszufinden, welche E-Mail-Adresse zu dieser ID gehört.

Signieren

Auch Signaturen betreffen zumeist E-Mails und sind dann komfortabel vom Benutzer abgeschirmt.

Wenn man mit gpg (oder einem GUI) normale Dateien (oder Datenströme) signiert, muss man wissen, dass es unterschiedliche Arten gibt, eine Signatur zu speichern (und natürlich auch unterschiedliche Arten von Signaturen):

Eine Signatur ist ein Hashwert der zu signierenden Daten, der mit dem privaten Schlüssel so verrechnet wird, dass mit Hilfe des öffentlichen Schlüssels nachgewiesen werden kann, dass der zugehörige Private Schlüssel die Signatur erzeugt hat. Eine Signatur ist deshalb nur so sicher wie der verwendete Hash. Wenn für den Hashwert eine Kollision erzeugt werden kann, rettet einen der längste PGP-Schlüssel nicht. gpg unterstützt eine Menge Hashfunktionen, allerdings kann es beim Einsatz der OpenPGP-Smartcard zu Problemen kommen. SHA-1 (aktuelle Standardeinstellung) ist derzeit sicher und funktioniert mit der Smartcard. Die Hash-Auswahl kann man mit der Option personal-digest-preferences steuern.

Speicherung von Daten und Signatur

Man kann Daten und Signatur in dieselbe Datei schreiben. Das passiert bei Verwendung der Kommandos --sign. Wenn man die zu signierenden Daten als unveränderte Datei behalten will (ohne eine neue vergleichbar große Datei) oder mehrere Dateien auf einmal signieren will, verwendet man --detach-sign (kann mit --encrypt kombiniert werden; aber eine Signatur muss man normalerweise nicht verschlüsseln). Wenn man auf diese Weise mehrere Dateien signiert, dann kann man die Signatur auch nur über alle Dateien gleichzeitig (und in derselben Reihenfolge) prüfen!

Erzeugen einer signierten Datei test.html.gpg, die die Daten von test.html enthält:

start cmd:> l test*
-rw-r--r-- 1 hl hauke  18 11. Jun 02:09 test2.html
-rw-r--r-- 1 hl hauke 810 11. Jun 02:09 test.html 

ec:0   02:09:52  hl@inno:~/tmp
start cmd:> gpg --sign test.html

Sie benötigen eine Passphrase, um den geheimen Schlüssel zu entsperren.
Benutzer: "Hauke Laging <hauke@laging.de>"
2048-Bit RSA Schlüssel, ID 0x3A403251, erzeugt 2010-03-04 (Hauptschlüssel-ID 0xECCB5814)


ec:0   02:10:23  hl@inno:~/tmp
start cmd:> l test*
-rw-r--r-- 1 hl hauke   18 11. Jun 02:09 test2.html
-rw-r--r-- 1 hl hauke  810 11. Jun 02:09 test.html
-rw-r--r-- 1 hl hauke 1,2K 11. Jun 02:10 test.html.gpg

Erzeugen einer Datei test.html.sig, die nur die Signatur von test.html enthält (also ohne die Bezugsdatei wertlos ist). Anschließend Überprüfung der Signatur.

start cmd:> gpg --detach-sign test.html

[...]

ec:0   02:11:02  hl@inno:~/tmp
start cmd:> l test*
-rw-r--r-- 1 hl hauke   18 11. Jun 02:09 test2.html
-rw-r--r-- 1 hl hauke  810 11. Jun 02:09 test.html 
-rw-r--r-- 1 hl hauke 1,2K 11. Jun 02:10 test.html.gpg
-rw-r--r-- 1 hl hauke  335 11. Jun 02:11 test.html.sig

ec:0   02:11:04  hl@inno:~/tmp
start cmd:> gpg test.html.sig
gpg: Signatur vom Fr 11 Jun 2010 02:11:01 CEST
gpg:                mittels RSA-Schlüssel 0x3A403251
gpg: Korrekte Signatur von "Hauke Laging <hauke@laging.de>"

Erzeugen einer gemeinsamen Signaturdatei test.html.all.sig für die beiden Dateien test.html und test2.html. Überprüfung scheitert, wenn nicht beide angegeben werden:

start cmd:> gpg --detach-sign --output test.html.all.sig test.html test2.html

[...]

ec:0   02:11:50  hl@inno:~/tmp
start cmd:> l test*
-rw-r--r-- 1 hl hauke   18 11. Jun 02:09 test2.html
-rw-r--r-- 1 hl hauke  810 11. Jun 02:09 test.html
-rw-r--r-- 1 hl hauke  335 11. Jun 02:11 test.html.all.sig
-rw-r--r-- 1 hl hauke 1,2K 11. Jun 02:10 test.html.gpg
-rw-r--r-- 1 hl hauke  335 11. Jun 02:11 test.html.sig

ec:1   02:12:37  hl@inno:~/tmp
start cmd:> gpg --verify test.html.all.sig test.html
gpg: Signatur vom Fr 11 Jun 2010 02:11:50 CEST
gpg:                mittels RSA-Schlüssel 0x3A403251
gpg: FALSCHE Signatur von "Hauke Laging <hauke@laging.de>"

ec:2   02:12:44  hl@inno:~/tmp
start cmd:> gpg --verify test.html.all.sig test.html test2.html
gpg: Signatur vom Fr 11 Jun 2010 02:11:50 CEST
gpg:                mittels RSA-Schlüssel 0x3A403251
gpg: Korrekte Signatur von "Hauke Laging <hauke@laging.de>"

Signierte Dateien kann man nur dann verwenden, wenn die Zielapplikation weiß, was das ist (z.B. ein PGP-fähiger Mailclient). Abgetrennte Signaturen lassen sich dagegen immer problemlos verwenden. Auf diese Weise kann man beispielsweise Webseiten signieren. Mit dem Ergebnis von --sign und --clearsign kann ein Browser nichts anfangen, aber man kann eine angetrennte Signatur erzeugen und verlinken. Man speichert dann die Webseite (als z.B. openpgp.html) und die Signatur (als z.B. openpgp.html.sig) und prüft dann die Gültigkeit der Signatur.

Signaturcodierung

--sign erzeugt eine "binäre" Signatur, also eine Datei, die man nicht problemlos mit einem normalen Editor lesen kann (weil sie nichtdruckbare Zeichen enthält). Wenn man die Signatur prüfen will, muss man die gesamten Daten auspacken. --clearsign eignet sich für Textdateien (und Ausschnitte davon). Das Ergebnis kann normal mit einem Editor gelesen werden:

echo hello world | gpg --clearsign

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

hello world
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.15 (GNU/Linux)

iQFMBAEBAgA2BQJMEXtrLxpodHRwOi8vd3d3LmhhdWtlLWxhZ2luZy5kZS9vcGVu
cGdwL3BvbGljeS5odG1sAAoJEFug+LU6QDJRiggH/2j23/ZzIOEoqjMWrcMbsI8/
Kfr7ikjIgrb1NfD+vVeDe7txQaDDN+/qKl18gPwNR4fjpVdg4gEmarFZ31R9bCJC
i1VtFTbRIdV5OXDpQ+vqYkG8x6AP6kOyUY6bEec8HKLD2M2FbBPgMjUMZ/d1hGlS
+ps5Pz1CutS1QsHn5lnRltvxsf8Fez3oJs811kq49gOd3YFkJycCGXBkRHM0OQcF
0NVwUSxDGKOlbQCDsCSPeTQo119MrC5u2bqs6svWQTiregHzUWsW93VA/fhZnX6j
956GMxoj4o6zDK8ZXbrClBBhywdwxcSxm8CGqFvGJQAggmYLpuBonsVTH6SWM1E=
=HCbr
-----END PGP SIGNATURE-----

Bei dem Kommandoaufruf habe ich --local-user ECCB5814 weglassen können, weil diese ID in der Konfigurationsdatei ~/.gnupg/options mit der Option default-key als Standard festgelegt ist. Dasselbe gilt für --recipient und encrypt-to.

Mehrfachsignatur

Man kann für eine Datei Signaturen mehrerer Schlüssel erzeugen und gemeinsam abspeichern. Das kann man einerseits erreichen, indem --local-user mehrfach angegeben wird, und andererseits, indem mehrere Signaturdateien zusammenkopiert werden (das funktioniert sowohl bei Textsignaturen als auch bei binären).

start cmd:> cat test.html.1.sig test.html.2.sig > test.html.beide.sig

ec:0   02:06:10  hl@inno:~/tmp
start cmd:> gpg --verify test.html.beide.sig test.html
gpg: Signatur vom Fr 23 Jul 2010 02:01:45 CEST
gpg:                mittels RSA-Schlüssel 0x3A403251
gpg: Korrekte Signatur von "Hauke Laging <hauke@laging.de>"
gpg: Beglaubigungsrichtlinie: http://www.hauke-laging.de/openpgp/policy.html

gpg: Signatur vom Fr 23 Jul 2010 02:01:45 CEST
gpg:                mittels RSA-Schlüssel 0xBB8A54D2
gpg: Korrekte Signatur von "Test Key (Demo) <test@key.inv>"
gpg:                     alias "Neue UID (nach der Signierung hinzugefügt) <test2@key.inv>"
gpg: Beglaubigungsrichtlinie: http://www.hauke-laging.de/openpgp/policy.html

Reihenfolge von Verschlüsselung und Signatur

Prinzipiell kann man Daten sowohl erst signieren und dann verschlüsseln als auch erst verschlüsseln und dann signieren. gpg unterstützt aber nur den ersten Weg direkt. Auf diese Weise wird nicht enthüllt, wer die Daten signiert hat. Das mag in speziellen Fällen relevant sein. Für Virenscanner ist es dagegen ein Alptraum. Wenn man verschlüsselte Daten signieren möchte, muss man gpg zweimal aufrufen, erst für die Verschlüsselung und dann zur Signierung der verschlüsselten Datei:

start cmd:> gpg --sign test.html.gpg

ec:130 02:54:02  hl@inno:~/tmp
start cmd:> gpg --output /dev/null test.html.gpg.gpg
gpg: Signatur vom Fr 11 Jun 2010 02:53:49 CEST
gpg:                mittels RSA-Schlüssel 0x3A403251
gpg: Korrekte Signatur von "Hauke Laging <hauke@laging.de>"

Das --output /dev/null unterdrückt die Ausgabe der Daten.

technische Details

Den folgenden Optionen begegnet man kaum einmal, aber auch sie haben ihren Sinn.

Policy URL

Eine digitale Signatur ist zunächst mal nur ein technischer Wert, dessen eindeutiger Aussagegehalt sich darauf beschränkt, dass der Signierende im Besitz des privaten Schlüssels und der signierten Daten (ganz genau: zumindest ihres Hashwerts) war. Auch wenn man unterstellt, dass der Signierende der legitime Besitzer des Schlüssels war, weiß man noch nicht, was diese Signatur zu bedeuten hat; vielleicht wollte der Signierer die Datei bloß gegen unerkannte Veränderungen sichern oder (für jemand anderen) bestätigen, dass sie zu einem bestimmten Zeitpunkt existiert hat. Man kann zweierlei tun, um dem Prüfer einer Signatur deren Interpretation zu erleichtern: Man kann die Information in eine zweite Datei packen und dann die Daten und diese Hilfsdatei gemeinsam signieren (die können dann auch nur gemeinsam geprüft werden, siehe die Signaturbeispiele oben). Die andere Möglichkeit, die sich vor allem für allgemein gültige Hinweise (wie bei der Zertifizierung von Schlüsseln) eignet, ist ein (Online-)Dokument, auf dessen URL von der Signatur aus verwiesen wird. Sinnvoll ist das natürlich nur, wenn das Dokument selber signiert ist. Bei Webseiten kann man das mit einem Link auf die abgretrennte Signatur (--detach-sign) der Datei realisieren.

Eine policy URL wird der Signatur mittels der Option --sig-policy-url URL angefügt. Die kann man sich, wenn alle Signaturen so einen Hinweis erhalten sollen, in die Konfigurationsdatei schreiben. Wenn man dieselbe URL für Schlüsselzertifizierungen und Datensignaturen verwendet, kann man statt --cert-policy-url und --sig-policy-url auch --set-policy-url verwenden.

Ablaufdatum (expire)

Man kann, in speziellen Fällen mag das sinnvoll sein, eine Signatur mit einem Ablaufdatum versehen, etwa für eine Art Ausweis (dann muss das Ablaufdatum nicht in den signierten Daten untergebracht werden) oder Signaturen, die regelmäßig erneuert werden sollen. Dies geht mit der Option --ask-sig-expire. Die gewünschte Gültigkeitsdauer wird dann von gpg abgefragt.

start cmd:> gpg --ask-sig-expire --detach-sign --local-user eccb5814 test.html
[...]

start cmd:> gpg --verify test.html.sig test.html
gpg: Signatur vom Fr 23 Jul 2010 01:23:00 CEST
gpg:                mittels RSA-Schlüssel 0x3A403251
gpg: Korrekte Signatur von "Hauke Laging <hauke@laging.de>"
gpg: Beglaubigungsrichtlinie: http://www.hauke-laging.de/openpgp/policy.html

gpg: Diese Signatur verfällt am Mo 02 Aug 2010 01:23:00 CEST.
eigene Zusatzinformationen

Man kann über die Option --sig-notation quasi beliebige Zusatzinformationen in einer Signatur unterbringen. Da ich dies bisher nicht gemacht habe, kann ich das nur der Vollständigkeit halber als Hinweis erwähnen, ohne darauf weiter einzugehen.

Diese Seite ist noch nicht fertig.