GPG - Signaturen überprüfen, ohne eine Vertrauenskette aufzubauen?


19

Ist es möglich, gpg (oder gpg4win) zu fragen, ob eine Datei von einer bestimmten öffentlichen Schlüsseldatei signiert wurde, ohne diesen Schlüssel importieren und signieren und ihm vertrauen zu müssen?

also sowas wie

gpg --using-key pubkey.txt --verify message.txt

im Gegensatz dazu müssen Sie Ihren eigenen privaten Schlüssel erstellen und dann tun

gpg --import pubkey.txt 
gpg --lsign-key [name within pubkey.txt]
# ... something to do with choosing trust levels
gpg --verify message.txt

1
Versuchen Sie festzustellen, ob der Befehl gpg --status-fd 1 --verify (thefile)in seiner Ausgabe als erste Zeichenfolge den Fingerabdruck des Schlüssels angibt, der die Signatur erstellt hat.
Harrymc

Ein Kontext hier: Wir haben ein System, das Dinge signiert. Wir geben den öffentlichen Schlüssel an Personen weiter, die möglicherweise Nachrichten von diesem System erhalten, damit diese überprüfen können, ob die Nachrichten nicht manipuliert wurden. Wir möchten den Empfängern jedoch nicht sagen, dass sie " irgendetwas vertrauen sollen , das mit diesem Schlüssel signiert ist", da dies zur Authentifizierung von Nachrichten von anderen Systemen (z. B. E-Mails von Freunden) verwendet werden kann.
ABl.

Wir möchten also jemandem eine Befehls- / Batch-Datei geben, die prüft, ob gpg sagt, dass diese Nachricht von diesem Schlüssel gesendet wurde. ohne ihre tägliche Nutzung von gpg für die Kommunikation mit anderen Menschen zu beeinträchtigen. Der Schlüssel sollte nur vertrauenswürdig sein, weil die Befehlszeile ihn anfordert, nicht weil GPG angewiesen wurde, ihm immer zu vertrauen.
ABl.

Antworten:


14

Sie müssen über den öffentlichen Schlüssel verfügen, um eine Signatur zu überprüfen, die mit dem entsprechenden privaten Schlüssel erstellt wurde. Sie müssen den Schlüssel jedoch nicht signieren oder lokal signieren. In diesem Fall erhalten Sie eine Warnung von GPG, dass der Schlüssel nicht vertrauenswürdig ist.

Hier ist ein Test, den ich mit einer Datei durchgeführt habe, die mit meinem eigenen Schlüssel signiert ist, aber auf einem System, auf dem der Schlüssel nicht importiert wurde:

[ben@seditious tmp]$ gpg -v --verify thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
gpg: Can't check signature: public key not found
[ben@seditious tmp]$ gpg -v --status-fd 1 --verify thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
[GNUPG:] ERRSIG 7FF2D37135C7553C 1 10 00 1380142299 9
[GNUPG:] NO_PUBKEY 7FF2D37135C7553C
gpg: Can't check signature: public key not found
[ben@seditious tmp]$ 

Leider funktioniert Harrys Vorschlag nicht, er extrahiert ein bisschen mehr Informationen, aber nicht genug, um von Nutzen zu sein.

Wie Sie sehen können, sind die meisten Informationen die Schlüssel-ID des Unterschlüssels, mit dem die Signatur erstellt wurde, und der Zeitpunkt, zu dem die Signatur erstellt wurde. Dies entspricht den Daten, die pgpdump (oder --list-packages) zur Verfügung stehen:

bash-3.2$ pgpdump thing.txt.gpg 
Old: Compressed Data Packet(tag 8)
    Comp alg - ZLIB <RFC1950>(comp 2)
Old: One-Pass Signature Packet(tag 4)(13 bytes)
    New version(3)
    Sig type - Signature of a binary document(0x00).
    Hash alg - SHA512(hash 10)
    Pub alg - RSA Encrypt or Sign(pub 1)
    Key ID - 0x7FF2D37135C7553C
    Next packet - other than one pass signature
Old: Literal Data Packet(tag 11)(24 bytes)
    Format - binary
    Filename - thing.txt
    File modified time - Thu Sep 26 06:51:39 EST 2013
    Literal - ...
Old: Signature Packet(tag 2)(412 bytes)
    Ver 4 - new
    Sig type - Signature of a binary document(0x00).
    Pub alg - RSA Encrypt or Sign(pub 1)
    Hash alg - SHA512(hash 10)
    Hashed Sub: signature creation time(sub 2)(4 bytes)
        Time - Thu Sep 26 06:51:39 EST 2013
    Sub: issuer key ID(sub 16)(8 bytes)
        Key ID - 0x7FF2D37135C7553C
    Hash left 2 bytes - f0 97 
    RSA m^d mod n(3066 bits) - ...
        -> PKCS-1
bash-3.2$ 

Wie Sie sehen können, enthält es den Hash-Algorithmus, die Details des Schlüsseltyps (mein Signaturschlüssel ist ein 3072-Bit-RSA-Unterschlüssel und die Schlüssel-ID des Unterschlüssels), aber es gibt nichts, um den Hauptschlüssel zu identifizieren. Dies sind nur Informationen Wird angezeigt, wenn Sie den öffentlichen Schlüssel haben und die Signatur überprüfen.

Dann habe ich meinen öffentlichen Schlüssel auf dieses System importiert und es erneut versucht:

[ben@seditious tmp]$ gpg -v --verify thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
gpg: using subkey 35C7553C instead of primary key 73590E5D
gpg: using PGP trust model
gpg: Good signature from "Ben M <ben@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M (backup email address) <benm@REDACTED>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: DB47 24E6 FA42 86C9 2B4E  55C4 321E 4E23 7359 0E5D
     Subkey fingerprint: B7F0 FE75 9387 430D D0C5  8BDB 7FF2 D371 35C7 553C
gpg: binary signature, digest algorithm SHA512
[ben@seditious tmp]$ 

Jetzt kann der Schlüssel identifiziert und mit dem Primärschlüssel abgeglichen werden. Es ist jedoch möglich, die Art dieser Warnungen wie folgt zu reduzieren:

[ben@seditious tmp]$ gpg -v --verify --trust-model always thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
gpg: using subkey 35C7553C instead of primary key 73590E5D
gpg: Good signature from "Ben M <ben@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M (backup email address) <benm@REDACTED>"
gpg: WARNING: Using untrusted key!
gpg: binary signature, digest algorithm SHA512
[ben@seditious tmp]$ 

Es gibt immer noch eine Warnung, dass es sich um einen nicht vertrauenswürdigen Schlüssel handelt, aber nicht massiv, und das Entfernen der Ausführlichkeit reduziert ihn nur auf Folgendes:

[ben@seditious tmp]$ gpg --verify --trust-model always thing.txt.gpg 
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
gpg: Good signature from "Ben M <ben@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M (backup email address) <benm@REDACTED>"
gpg: WARNING: Using untrusted key!
[ben@seditious tmp]$ 

Der öffentliche Schlüssel wird für die Überprüfungsphase benötigt, da er verwendet wird, um vom Unterzeichner generierte Daten mit ihrem privaten Schlüssel abzugleichen. Es kann in einfachen Worten als Ergänzung der Verschlüsselung betrachtet werden, bei der der private Schlüssel zum Entschlüsseln von mit dem öffentlichen Schlüssel verschlüsselten Daten benötigt wird.

Hinweis: Ich habe die UIDs in diesem Beispiel ein wenig angepasst, aber jeder, der diesen Schlüssel erhält, wird sehen, was er wirklich ist. Ansonsten ist die Ausgabe ein direktes Kopieren und Einfügen.

BEARBEITEN: Sie können die öffentliche Schlüsseldatei direkt wie einen Schlüsselbund aufrufen, wenn Sie sie im nicht-ASCII-gepanzerten Format haben (dh eine .gpg-Datei anstelle einer .asc-Datei). Trotzdem benötigen Sie den öffentlichen Schlüssel. Dazu sieht der Befehl folgendermaßen aus:

[ben@seditious ~]$ gpg -v --no-default-keyring --keyring /tmp/mykey.gpg --verify /tmp/thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
gpg: using subkey 35C7553C instead of primary key 73590E5D
gpg: using PGP trust model
gpg: Good signature from "Ben M <ben@REDACTED>"
gpg:                 aka "Ben M (backup email address) <benm@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: DB47 24E6 FA42 86C9 2B4E  55C4 321E 4E23 7359 0E5D
     Subkey fingerprint: B7F0 FE75 9387 430D D0C5  8BDB 7FF2 D371 35C7 553C
gpg: binary signature, digest algorithm SHA512
[ben@seditious ~]$ 

Wenn ich mir Ihre Ergebnisse ansehe, bin ich zu dem genau entgegengesetzten Ergebnis gekommen. Ich habe Ihre Ausgabe in meiner Antwort verwendet, habe Sie aber dafür ausgezeichnet.
Harrymc

Der Teil , den Sie auf die sich die Langform der Schlüssel - ID des Unterschlüssel (technisch die volle Schlüssel - ID ist der Fingerabdruck) ist der einzige identifizierbare Teil. Ohne den Besitz des öffentlichen Schlüssels können Sie den Hauptschlüssel jedoch nicht identifizieren oder die Signatur überprüfen. Die Details dazu finden Sie in Abschnitt 5.2 von RFC 4880 (mit ein wenig in Abschnitt 2.2, aber in Abschnitt 5.2 finden Sie die nützlichen Informationen). Wenn ich mich irre, beweise die Verifizierung ohne eine Kopie des Schlüssels (Hinweis: Du kannst es nicht mit meinen Beispielen machen).
Ben

Nach Ihrer Schlussfolgerung zu --verify funktioniert dies nur, wenn der Schlüssel verfügbar ist. Andernfalls kehren Sie zum ersten Beispiel in meiner Antwort zurück, in dem die Schlüssel-ID und die Uhrzeit der Signatur überprüft werden, der Schlüssel jedoch nicht gefunden wird.
Ben

Ja, eine vollständige Identifizierung ist natürlich nur anhand der Schlüssel-ID nicht möglich. Ich habe meine Antwort geändert, um deutlich zu machen, dass dies nur eine Heuristik ist. Ihre Schlussfolgerung ist, dass das, wonach das Poster fragt, unmöglich ist, aber das liegt wahrscheinlich daran, dass das Poster das Wort "Verify" verwendet hat, das zu stark ist.
Harrymc

1
Das stimmt, das OP verwendet die Begriffe wahrscheinlich nicht richtig und ich habe sie möglicherweise auch an einigen Stellen verfälscht (ich habe letzte Nacht viel geniest ). Wenn es bei seiner Frage nur darum ging, eine Signatur zu validieren, ohne einen Schlüssel zu importieren, dann zeigt das Beispiel in meiner Bearbeitung, wie dies gemacht werden kann, aber nur, wenn dieser Schlüssel im OpenPGP-Format (pubkey.gpg) vorliegt. Es funktioniert nicht, wenn der exportierte Schlüssel im ASCII-gepanzerten Format (pubkey.asc) vorliegt.
Ben

2

Wenn Sie mit dem Versand eines Schlüsselbunds anstelle einer öffentlichen Schlüsseldatei einverstanden sind, möchten Sie wahrscheinlich gpgveher verwenden als gpg:

gpgv --keyring key.ring somefile.txt

0

Wenn Ihr Wort "verifizieren" in der Frage "absolut verifizieren" bedeutet, muss natürlich ein öffentlicher Schlüssel importiert werden, um ein signiertes Dokument vollständig zu verifizieren. Wenn dies jedoch "identifizieren" bedeutet, beschreibe ich im Folgenden eine Heuristik, die erkennen kann, ob eine Gruppe von Dokumenten alle mit derselben Signatur signiert wurde.

Gemäß den von @Ben durchgeführten Tests zur Überprüfung meines Kommentars besteht die Möglichkeit, dass der folgende Befehl verwendet werden kann, um den Signaturschlüssel heuristisch anzuzeigen:

gpg --status-fd 1 --verify thefile.gpg

Der Test von Ben ergab das folgende Ergebnis. Bemerkenswert sind die Werte von ERRSIG und NO_PUBKEY sowie der Wert von "RSA-Schlüssel-ID", der teilweise in beiden enthalten ist, wie folgt:

[ben@seditious tmp]$ gpg -v --status-fd 1 --verify thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
[GNUPG:] ERRSIG 7FF2D37135C7553C 1 10 00 1380142299 9
[GNUPG:] NO_PUBKEY 7FF2D37135C7553C
gpg: Can't check signature: public key not found

Beachten Sie über der Zeichenfolge 7FF2D37135C7553C. Dieselbe Zeichenfolge befindet sich im Fingerabdruck des Schlüssels, der nach dem Import des Schlüssels gemeldet wird:

[ben@seditious ~]$ gpg -v --no-default-keyring --keyring /tmp/mykey.gpg --verify /tmp/thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
gpg: using subkey 35C7553C instead of primary key 73590E5D
gpg: using PGP trust model
gpg: Good signature from "Ben M <ben@REDACTED>"
gpg:                 aka "Ben M (backup email address) <benm@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg:                 aka "Ben M <ben.m@REDACTED>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: DB47 24E6 FA42 86C9 2B4E  55C4 321E 4E23 7359 0E5D
     Subkey fingerprint: B7F0 FE75 9387 430D D0C5  8BDB 7FF2 D371 35C7 553C
gpg: binary signature, digest algorithm SHA512

Diese Zeichenfolge befindet sich im unteren Teil des Fingerabdrucks (Teilschlüssel oben) und kann daher möglicherweise zur Identifizierung des Schlüssels verwendet werden. Der "Primärschlüssel-Fingerabdruck" sollte wahrscheinlich zusätzlich zum Unterschlüssel überprüft werden.

Die Zeichenfolge "RSA-Schlüssel-ID" ist in beiden Ausgaben identisch und wird auch als letzter Teil des Fingerabdrucks gefunden, sodass es möglicherweise ausreicht, die Signatur selbst zu identifizieren. In diesem Fall ist es gpg --verifymöglicherweise ausreichend , nur die Ausgabe von zu verwenden, um die Signatur auf einfachere Weise zu identifizieren.

[ben@seditious tmp]$ gpg -v --verify thing.txt.gpg 
gpg: original file name='thing.txt'
gpg: Signature made Thu 26 Sep 2013 06:51:39 AM EST using RSA key ID 35C7553C
gpg: Can't check signature: public key not found

Meine GPG-Kenntnisse reichen nicht aus, um diese Methode vollständig zu validieren. Sie sollten sie daher an weiteren Beispieldateien ausprobieren. Wenn dies funktioniert, können Sie die Dateien nach Signaturen sortieren, müssen jedoch den Schlüssel importieren, um die Identität des Unterzeichners zu ermitteln.

Um es noch einmal deutlich zu machen: Diese Methode kann eine Signatur nicht vollständig identifizieren. Es ist nur eine Möglichkeit, signierte Dokumente heuristisch zu sortieren.


Eine Signatur enthält genügend Daten, um den zum Erstellen verwendeten Schlüssel zu identifizieren, und kann in Verbindung mit den Schlüsselservern zum Auffinden des Hauptschlüssels verwendet werden (vorausgesetzt, ein signierender Unterschlüssel wurde wie in meinen Beispielen verwendet). Ohne eine Kopie des öffentlichen Schlüssels im OpenPGP-Format (entweder in einem Schlüsselbund oder wie in meinem letzten Beispiel) ist die Validierung der Signatur nicht möglich, da die Fingerabdruck- / Schlüssel-ID nicht ausreicht, um dies zu berechnen.
Ben

@Ben: Ich wiederhole, dass dies nur eine Heuristik ist. Dies ist die beste Methode, um die Frage des Posters zu beantworten: "Überprüfen Sie, ob eine Datei von einer bestimmten öffentlichen Schlüsseldatei signiert wurde, ohne diesen Schlüssel importieren und signieren und ihm vertrauen zu müssen ".
Harrymc

würde es die Frage klarer machen, wenn ich sagen würde, dass wir allen Schlüsseln in der .pub-Datei vertrauen (um diese bestimmte Datendatei zu überprüfen) und dass die Gründe, warum wir uns für diese .pub-Datei entscheiden, außerhalb des Geltungsbereichs von liegen irgendwelche GPG-Aktivitäten?
ABl.

Ist die Heuristik, die Schlüssel in der PUB-Datei aufzulisten und ihre RSA-Schlüssel-ID zu vergleichen, hilfreich? Ich habe hier kein gpg zum Ausprobieren, aber vielleicht so etwas wie "gpg --no-default-keyring --keyring <pub-file> --list-keys".
Harrymc
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.