GPG - weryfikacja podpisów bez tworzenia łańcucha zaufania?

19

Czy można poprosić gpg (lub gpg4win) o sprawdzenie, czy plik został podpisany przez określony plik klucza publicznego, bez konieczności importowania, podpisywania i ufania temu kluczowi?

tj. coś podobnego

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

w przeciwieństwie do konieczności tworzenia własnego klucza prywatnego, a następnie robienia tego

gpg --import pubkey.txt 
gpg --lsign-key [name within pubkey.txt]
# ... something to do with choosing trust levels
gpg --verify message.txt
OJW
źródło
1
Spróbuj sprawdzić, czy polecenie gpg --status-fd 1 --verify (thefile)podaje jako wynik pierwszy odcisk palca klawisza, który utworzył podpis.
harrymc
Tu jakiś kontekst: mamy system, który podpisuje różne rzeczy. Dajemy klucz publiczny osobom, które mogą odbierać wiadomości z tego systemu, aby mogły sprawdzić, czy wiadomości nie zostały zmienione. Nie chcemy jednak informować odbiorców, aby „ufali cokolwiek podpisanego tym kluczem”, ponieważ może to służyć do uwierzytelniania wiadomości z innych systemów (np. Wiadomości e-mail od znajomych).
OJW
Więc chcemy dać komuś plik polecenia / partii, który sprawdza „czy gpg mówi, że ta wiadomość została wysłana przez ten klucz?” bez ingerowania w codzienne korzystanie z gpg do komunikowania się z innymi ludźmi. Kluczowi należy ufać tylko dlatego, że wymaga tego wiersz poleceń, a nie dlatego, że GPG kazano mu zawsze ufać.
OJW

Odpowiedzi:

14

Musisz mieć klucz publiczny, aby zweryfikować podpis wykonany odpowiednim kluczem prywatnym, ale nie musisz podpisywać ani nawet lokalnie podpisywać klucza. W takim przypadku otrzymasz ostrzeżenie od GPG, że klucz jest niezaufany.

Oto test, który wykonałem za pomocą pliku podpisanego własnym kluczem, ale w systemie, w którym klucz nie został zaimportowany:

[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]$ 

Niestety sugestia Harry'ego nie działa, wyciąga trochę więcej informacji, ale nie na tyle, by była przydatna.

Jak widać, najwięcej uzyskanych informacji to identyfikator klucza podklucza użytego do złożenia podpisu oraz godzina jego złożenia. To pasuje do danych dostępnych dla pgpdump (lub --list-packets):

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$ 

Jak widać, zapewnia algorytm mieszania, szczegóły typu klucza (mój klucz podpisujący to 3072-bitowy podklucz RSA i identyfikator klucza podklucza, ale nie ma nic, co mogłoby zidentyfikować klucz główny. Ta informacja jest tylko ujawnione, gdy masz klucz publiczny i zweryfikuj podpis.

Następnie zaimportowałem mój klucz publiczny do tego systemu i spróbowałem ponownie:

[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]$ 

Teraz jest w stanie zidentyfikować klucz i dopasować go do klucza podstawowego. Możliwe jest jednak ograniczenie charakteru takich ostrzeżeń:

[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]$ 

Nadal jest ostrzeżenie, że jest to niezaufany klucz, ale nie tak masowo, a usunięcie gadatliwości ogranicza go tylko do tego:

[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]$ 

Klucz publiczny jest wymagany na etapie weryfikacji, ponieważ służy do dopasowania danych wygenerowanych przez osobę podpisującą z ich kluczem prywatnym. Mówiąc najprościej, można go traktować jako uzupełnienie szyfrowania, w którym klucz prywatny jest potrzebny do dekodowania danych zaszyfrowanych na klucz publiczny.

Uwaga: trochę poprawiłem UID w tym przykładzie, ale każdy, kto dostanie ten klucz, zobaczy, kim naprawdę jest. W przeciwnym razie dane wyjściowe to prosta kopia i wklej.

EDYCJA: Możesz wywołać plik klucza publicznego bezpośrednio jak brelok, jeśli masz go w zbrojonym formacie innym niż ASCII (tzn. Plik .gpg zamiast pliku .asc). Mimo to nadal potrzebujesz klucza publicznego. Aby to zrobić, polecenie wygląda następująco:

[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 ~]$ 
Ben
źródło
Patrząc na twoje wyniki, doszedłem do dokładnie przeciwnego wniosku. Wykorzystałem twój wynik w mojej odpowiedzi, ale przypisałem ci to.
harrymc
Część, do której się odwołujesz, to długa forma identyfikatora klucza podklucza (technicznie pełnym identyfikatorem klucza jest odcisk palca) jest jedyną możliwą do zidentyfikowania częścią. Bez posiadania klucza publicznego nie można jednak zidentyfikować klucza głównego ani zweryfikować podpisu. Szczegółowe informacje na ten temat znajdują się w sekcji 5.2 RFC 4880 (nieco w części 2.2, ale 5.2 jest tam, gdzie są przydatne rzeczy). Jeśli się mylę, udowodnij weryfikację bez kopii klucza (wskazówka: nie możesz tego zrobić na moich przykładach).
Ben
Również na podstawie wniosku dotyczącego --verify działa to tylko wtedy, gdy klucz jest dostępny, w przeciwnym razie wróć do pierwszego przykładu w mojej odpowiedzi, w którym weryfikowany jest identyfikator klucza i godzina podpisu, ale klucza nie znaleziono.
Ben
Tak, pełna identyfikacja nie jest oczywiście możliwa tylko na podstawie identyfikatora klucza. Zmodyfikowałem swoją odpowiedź, aby wyraźnie stwierdzić, że jest to tylko heurystyka. Wniosek jest taki, że to, o co pyta plakat, jest niemożliwe, ale prawdopodobnie dlatego, że plakat użył słowa „sprawdź”, co jest zbyt mocne.
harrymc
1
To prawda, OP prawdopodobnie nie używa właściwie terminów i być może sfałszowałem je również w kilku miejscach ( wczoraj dużo kichałem ). Jeśli jego pytanie dotyczyło tylko weryfikacji sig bez importowania klucza, to przykład w mojej edycji pokazuje, jak można to zrobić, ale tylko jeśli ten klucz jest w formacie OpenPGP (pubkey.gpg). Nie działa, jeśli eksportowany klucz jest w zbrojonym formacie ASCII (pubkey.asc).
Ben
2

Jeśli jesteś OK z wysyłką do bazy kluczy, zamiast pliku klucza publicznego, prawdopodobnie chcesz użyć gpgvzamiast gpg:

gpgv --keyring key.ring somefile.txt
womble
źródło
0

Jeśli słowo „zweryfikuj” w pytaniu oznacza „absolutnie zweryfikuj”, to oczywiście klucz publiczny musi zostać zaimportowany, aby całkowicie zweryfikować podpisany dokument. Jeśli jednak oznacza to „identyfikacja”, poniżej opiszę heurystykę, która może stwierdzić, czy wszystkie dokumenty zostały podpisane tym samym podpisem.

Zgodnie z testami przeprowadzonymi przez @Ben w celu zweryfikowania mojego komentarza, istnieje możliwość użycia następującego polecenia do heurystycznego wskazania klucza podpisującego:

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

Test Bena dał wynik poniżej. Na uwagę zasługują wartości ERRSIG i NO_PUBKEY, a także wartość „ID klucza RSA”, która jest częściowo w nich zawarta, jak następuje:

[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

Uwaga nad ciągiem 7FF2D37135C7553C. Ten sam ciąg znajduje się w odcisku palca klucza, który jest zgłaszany po zaimportowaniu klucza:

[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

Ciąg ten znajduje się jako dolna część odcisku palca (podklucz powyżej), więc może być prawdopodobnie użyty do identyfikacji klucza. Oprócz podklucza prawdopodobnie należy też zweryfikować „odcisk palca klucza głównego”.

Ciąg „Identyfikator klucza RSA” jest identyczny na obu wyjściach i znajduje się również jako ostatnia część odcisku palca, więc może być możliwe, że sam wystarczy do zidentyfikowania podpisu. W takim przypadku użycie tylko danych wyjściowych gpg --verifymoże wystarczyć do zidentyfikowania podpisu w prostszy sposób.

[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

Moja wiedza na temat GPG nie jest wystarczająca, aby w pełni zweryfikować tę metodę, dlatego powinieneś wypróbować ją na większej liczbie przykładowych plików. Jeśli to działa, możesz posortować pliki według ich podpisów, ale będziesz musiał zaimportować klucz, aby znaleźć tożsamość podpisanego.

Jasne stwierdzenie: ta metoda nie może w pełni zidentyfikować podpisu. To tylko sposób heurystycznego sortowania podpisanych dokumentów.

harrymc
źródło
Podpis zawiera wystarczającą ilość danych, aby zidentyfikować klucz użyty do jego utworzenia, aw połączeniu z serwerami kluczy można go użyć do zlokalizowania klucza głównego (zakładając, że użyto podklucza podpisującego, jak w moich przykładach). Bez kopii klucza publicznego w formacie OpenPGP (w breloku lub w moim ostatnim przykładzie) weryfikacja podpisu nie jest możliwa, ponieważ odcisk palca / identyfikator klucza nie wystarcza do obliczenia tego.
Ben
@Ben: Powtarzam, że jest to tylko heurystyka, co jest najlepsze, co można zrobić, odpowiadając na pytanie plakatu: „sprawdź, czy plik został podpisany przez określony plik klucza publicznego, bez konieczności importowania, podpisywania i ufania temu kluczowi „.
harrymc
czy wyjaśniłoby to pytanie, gdybym powiedział, że ufamy jakimkolwiek kluczom w pliku .pub (w celu sprawdzenia tego konkretnego pliku danych) oraz że powody, dla których zdecydowaliśmy się zaufać temu plikowi .pub, są poza zakresem jakaś aktywność GPG?
OJW
Czy heurystyka polegająca na umieszczeniu kluczy w pliku .pub i porównaniu ich identyfikatora klucza RSA będzie przydatna? Nie mam tutaj gpg do wypróbowania, ale może coś w stylu „gpg - no-default-keyring --keyring <pub-plik> --list-keys”.
harrymc