Das binäre Format von GnuPG ist zwar platzsparend, es ist jedoch auf Flexibilität ausgelegt, nicht auf absolut minimale Nachrichtengrößen (normalerweise ist die eigentliche Nachricht viel größer als einige Bytes). Die minimale "übliche" OpenPGP-Nachricht ist 31 Bytes groß, aber Sie können immer noch mit etwas zusätzlichem Aufwand auf 26 Bytes reduzieren, was die kleinste mögliche OpenPGP v4-Nachricht für Einzelbyte-Inhalte ist.
Eine OpenPGP-Nachricht zerlegen, Bytes zählen
Wenn Sie sich RFC 4880 ansehen, können Sie eine minimale Länge einer Nachricht ableiten, die Sie nicht unterschreiten dürfen.
Schauen wir uns die Ausgabe des von Ihnen erstellten Befehls an:
$ echo -n a|gpg --symmetric --compress-algo none --disable-mdc --s2k-mode 0 -o-|gpg --list-packets gpg: Note: simple S2K mode (0) is strongly discouraged gpg: AES encrypted data gpg: encrypted with 1 passphrase gpg: WARNING: message was not integrity protected
Das erste Paket ist ein mit einem symmetrischen Schlüssel verschlüsseltes Sitzungsschlüsselpaket . Es enthält eine Kopie des Sitzungsschlüssels, verschlüsselt durch die Passphrase unter Verwendung der String-to-Key-Mechanik. OpenSSL tut dies nicht, aber Sie können dies nicht überspringen, wenn Sie nicht den Passphrase, sondern den Sitzungsschlüssel angeben und den Sitzungsschlüssel separat angeben (siehe unten). Dieses Paket ist sechs Byte groß und besteht aus:
- 2 Byte Paketkopf (Tag und Länge)
- 1 Byte Versionsnummer
- 1 Byte symmetrischer Algorithmus-ID
- 2 Byte s2k-Bezeichner (1 Byte "einfacher s2k-Modus", 1 Byte Hash-Funktionsalgorithmus)
# off=0 ctb=8c tag=3 hlen=2 plen=4 :symkey enc packet: version 4, cipher 7, s2k 0, hash 10
Nun beginnen die verschlüsselten Datenpakete. Es beinhaltet:
- 2 Byte Paketkopf (Tag und Länge)
- Zufälliges Präfix mit 18 Bytes (anstelle von 0 Bytes IV verwendet OpenPGP CFB ein zufälliges Präfix in der Größe des Chiffrierblocks und wiederholt die ersten beiden Bytes; AES verwendet 128 Bits = 16 Bytes als Chipherblocklänge.)
# off=6 ctb=c9 tag=9 hlen=2 plen=26 new-ctb :encrypted data packet: length: 26
OpenPGP speichert die Nachricht immer in einem literalen Datenpaket, wodurch einige Metadaten hinzugefügt werden. Durch das Deaktivieren der Komprimierung werden zumindest die zusätzlichen Komprimierungsheader entfernt. Dieses Paket fügt schließlich weitere 9 Bytes hinzu:
- 2 Byte Paketkopf (Tag und Länge)
- 1 Byte Datenformat
- 1 Byte Dateinamen-Stringlänge (Wert Null, kein Dateiname folgt)
- 4 Byte Zeitstempel
- 1 Byte Inhalt
# off=26 ctb=cb tag=11 hlen=2 plen=6 new-ctb :literal data packet: mode b (62), created 1503680075, name="", raw data: 0 bytes
Zum Schluss: Sie können kein einzelnes weiteres Byte speichern - es sei denn, Sie lassen die String-to-Key-Ableitung weg und verwenden direkt den Sitzungsschlüssel anstelle einer Passphrase.
Die String-to-Key-Funktion auslassen
GnuPG ermöglicht das Lesen und Einstellen des Sitzungsschlüssels mit --show-session-key
und --override-session-key
. Beim Lesen des Kapitels zur Nachrichtenzusammensetzung war ich tatsächlich überrascht, dass gültige OpenPGP-Nachrichten überhaupt kein Paket erfordern, das die Verschlüsselung des Sitzungsschlüssels definiert. GnuPG unterstützt zwar diese Art der Operation, aber ich würde nicht auf andere Implementierungen setzen, da dies eine sehr esoterische Art ist, OpenPGP zu verwenden.
OpenPGP Message :- Encrypted Message | Signed Message | Compressed Message | Literal Message. Encrypted Message :- Encrypted Data | ESK Sequence, Encrypted Data. Encrypted Data :- Symmetrically Encrypted Data Packet | Symmetrically Encrypted Integrity Protected Data Packet
Dadurch sollten die 6 Bytes des mit einem symmetrischen Schlüssel verschlüsselten Sitzungsschlüsselpakets gespeichert werden.
Erstellen einer OpenPGP-Nachricht ohne mit Symmetric-Key verschlüsseltes Sitzungsschlüsselpaket
Ich habe keinen Weg gefunden, GnuPG dazu zu bringen, einen vordefinierten Sitzungsschlüssel zu verwenden. Sie können jedoch eine symmetrisch verschlüsselte Nachricht generieren, den Sitzungsschlüssel während der Entschlüsselung extrahieren und dann die Nachricht aufteilen.
Nachricht verschlüsseln:
$ echo -n a|gpg --symmetric --compress-algo none --disable-mdc --s2k-mode 0 -o message.gpg
Extrahieren des Sitzungsschlüssels (fragt nach der Passphrase):
$ gpg --show-session-key 0 --decrypt message.gpg gpg: AES encrypted data gpg: encrypted with 1 passphrase gpg: session key: '7:F7FBBA6E0636F890E56FBBF3283E524C' agpg: WARNING: message was not integrity protected
Teilen Sie die OpenPGP-Nachricht in einzelne Pakete auf:
$ gpgsplit message.gpg
Der Ordner enthält jetzt vier Dateien: das verschlüsselte message.gpg
, das unverschlüsselte message
, das mit dem symmetrischen Schlüssel verschlüsselte Sitzungsschlüsselpaket 000001-003.sym_enc
und schließlich das verschlüsselte Datenpaket 000002-009.encrypted
.
$ ls -l total 16 -rw-r--r-- 1 jenserat jenserat 6 Aug 25 19:36 000001-003.sym_enc -rw-r--r-- 1 jenserat jenserat 29 Aug 25 19:36 000002-009.encrypted -rw-r--r-- 1 jenserat jenserat 1 Aug 25 19:04 message -rw-r--r-- 1 jenserat jenserat 35 Aug 25 19:33 message.gpg
Sie können auch cat
die einzelnen Paketdateien konfigurieren, um zurück zu gelangen message.gpg
- diese beiden Dateien sind nur Teile davon message.gpg
. Beachten Sie die Dateigrößen, die genau den oben diskutierten Größen entsprechen (während natürlich die Größe des literalen Datenpakets im verschlüsselten Datenpaket enthalten ist, da gpgsplit
die Passphrase nicht bekannt ist)!
Entschlüsseln eines separaten verschlüsselten Datenpakets
Dieser Schritt ist ziemlich einfach:
$ gpg --override-session-key '7:F7FBBA6E0636F890E56FBBF3283E524C' --decrypt 000002-009.encrypted agpg: WARNING: message was not integrity protected
Übersehen Sie nicht die a
vor der Warnmeldung, die die Ausgabe ist.
Bedeutung der Warnmeldungen
GnuPG druckte zwei Warnmeldungen.
gpg: Hinweis: Der einfache S2K-Modus (0) wird dringend empfohlen
Dies liegt daran, dass der einfache S2K-Modus Brute-Force- und Wörterbuch-Angriffe auf die Passphrase kostengünstig und einfach macht, da kein Hashing und kein Salz verwendet wird.
Letzteres ermöglicht natürlich die Verwendung desselben Sitzungsschlüssels für mehrere Dateien, die mit derselben Passphrase verschlüsselt sind. Beachten Sie jedoch die Konsequenzen.
gpg: WARNUNG: Die Nachricht wurde nicht vor Integrität geschützt
Diese Warnmeldung weist darauf hin, dass die Nachricht möglicherweise von einem Angreifer geändert wurde, ohne dass der entschlüsselnde Teilnehmer davon Kenntnis nehmen kann. Dies liegt an --disable-mdc
-, das natürlich einige Bytes für die verschlüsselte Prüfsumme der Datei speichert. Sie können es selbst ausprobieren, indem Sie das letzte Byte in einem Hex-Editor ändern.