Jak podpisywać pliki za pomocą narzędzi wiersza polecenia Ubuntu i własnych kluczy?

14

Chcę podpisać niektóre napisane przeze mnie pliki kodu Python, ponieważ są to moduły wtyczek do jednego z moich projektów. Aby go rozpowszechnić, chcę, aby użytkownik był pewien, że wtyczka jest zweryfikowana i bezpieczna (ponieważ została napisana przeze mnie lub osobę, której ufam) i nie została zmodyfikowana.

Oprogramowanie to po prostu projekt hobby typu open source, dlatego nie chcę wydawać pieniędzy na zakup oficjalnego certyfikatu. Zamiast tego zakładam, że program główny jest zawsze ważny i można mu ufać bez dodatkowej weryfikacji. Jeśli ktoś pobierze go z innego miejsca niż moje repozytorium GitHub, to z jego winy.

Z tego, co przeczytałem, podpisywanie odbywa się zwykle przez utworzenie asymetrycznej pary kluczy, obliczenie silnej kryptograficznej wartości skrótu (np. SHA-512) z pliku kodu, szyfrowanie skrótu za pomocą mojego klucza prywatnego i przechowywanie tej sygnatury w osobnym pliku do wysłania z oryginalnym plikiem kodu.
Główny program będzie musiał następnie odszyfrować podpis przy użyciu klucza publicznego zapisanego w postaci zwykłego tekstu w kodzie źródłowym głównego programu, obliczyć tę samą funkcję skrótu pliku kodu, a następnie porównać go z odszyfrowanym. Jeśli są zgodne, wtyczce można zaufać.

Więc teraz moje pytanie:

Jak łatwo utworzyć silną asymetryczną parę kluczy za pomocą narzędzi Ubuntu i jak łatwo obliczyć kryptograficzną wartość skrótu pliku?
Świetnie byłoby zautomatyzować proces podpisywania w skrypcie (używając zawsze tego samego klucza).

Bajt Dowódca
źródło

Odpowiedzi:

19

Duża część tej odpowiedzi została pobrana z Arch Wiki i dokumentacji GnuPG . Wszelkie zalecenia zawarte w tej odpowiedzi są wyłącznie moim zdaniem i powinny być przyjmowane z toną soli.

Tworzenie klucza PGP

GUI

  1. Otwórz aplikację Hasła i klucze (aka seahorse) i kliknij +(lub przejdź do Plik -> Nowy lub naciśnij CtrlN), aby zobaczyć:

    okno dialogowe nowego przedmiotu dla konika morskiego

  2. Wybierz klucz PGP i wprowadź swoje dane. Podszywam się pod Byte Commander:

    okno dialogowe z kluczowymi szczegółami

    RSA i 2048 bitów są w porządku do większości celów. Jeśli chcesz go używać tylko do podpisywania, wybierz z menu rozwijanego opcję RSA (tylko podpis) , ale nie jest to konieczne - można to zrobić za pomocą podkluczy . Możesz skomentować. Przydatne jest także zachowanie daty ważności klucza. Kliknij Create.

  3. Wprowadź odpowiednio długie hasło (i mam na myśli długie , mój przykład jest krótki, IMO) i kliknij Ok:

    okno dialogowe wprowadzania hasła

    Konik morski nie wydaje się mieć żadnych informacji zwrotnych, w przeciwieństwie do CLI. Poczekaj chwilę, robiąc wszystko, co chcesz, podczas gdy zbiera entropię i tworzy klucz. To może chwilę potrwać. Następnie zobaczysz, że wpisują klucz w sekcji Klucze PGP :

    lista kluczy pgp

CLI

Aby wygenerować klucz z wiersza poleceń, po prostu uruchom gpg --gen-key. Poprosi Cię o te same szczegóły, które zrobił GUI:

$ gpg --gen-key 
gpg (GnuPG) 1.4.16; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0) 1y
Key expires at Tuesday 27 September 2016 03:45:19 PM IST
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and E-mail Address in this form:
    "Heinrich Heine (Der Dichter) <[email protected]>"

Real name: Byte Commander
E-mail address: [email protected]
Comment: 
You selected this USER-ID:
    "Byte Commander <[email protected]>"

Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

passphrase not correctly repeated; try again.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, use the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy!  (Need 186 more bytes)
.....+++++
+++++
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, use the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy!  (Need 80 more bytes)
....+++++

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy!  (Need 83 more bytes)
...+++++
gpg: key 8AE670A6 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2016-09-26
pub   2048R/8AE670A6 2015-09-28 [expires: 2016-09-27]
      Key fingerprint = 82D9 0644 B265 8E75 1E01  538B B479 3CF4 8AE6 70A6
uid                  Byte Commander <[email protected]>
sub   2048R/0E2F4FD8 2015-09-28 [expires: 2016-09-27]

Zwróć uwagę, jak GnuPG mówi nam, że potrzebuje więcej entropii. Szkoda, że ​​konik morski też. Ale z drugiej strony wydaje się, że GnuPG zachowuje się jak Oliver Twist. : P

Publikowanie klucza

Teraz musimy pobrać nasz klucz publiczny, aby ludzie mogli zweryfikować jego użycie.

GUI

Wróć do listy kluczy PGP w seahorseaplikacji (patrz ostatni zrzut ekranu). Wybierz klucze, które chcesz wyeksportować, aw menu Zdalne wybierz Synchronizuj i opublikuj klucze :

wprowadź opis zdjęcia tutaj

SyncPrzycisk będzie wyłączony, jeśli nie wybrano serwer opublikować. Zrób to, klikając Key Serversprzycisk:

wprowadź opis zdjęcia tutaj

Wybrałem serwer Ubuntu.

Teraz możesz kliknąć Syncprzycisk i opublikować go na serwerze kluczy Ubuntu (przepraszam za spam, Ubuntu!).

CLI

Dzięki interfejsowi CLI potrzebujesz identyfikatora klucza, który chcesz opublikować. Jest to ostatni wiersz wyniku podczas tworzenia key ( 8AE670A6). Jeśli nie pamiętasz, co to jest, po prostu biegnij gpg --list-keys. Opublikować:

$ gpg  --keyserver pgp.mit.edu --send-keys 8AE670A6
gpg: sending key 8AE670A6 to hkp server pgp.mit.edu

Przepraszam, MIT .

Podpisywanie

Nie znam jeszcze wygodnej metody podpisywania dokumentu w GUI.

Po utworzeniu pliku, który chcesz podpisać, przejdź do terminala. Spróbuj gpg --list-keys:

$ gpg --list-keys       
/home/muru/.gnupg/pubring.gpg
---------------------------
pub   2048R/F7878B0C 2015-09-28 [expires: 2016-09-26]
uid                  Byte Commander <[email protected]>
sub   2048R/345B9A4F 2015-09-28 [expires: 2016-09-26]

Możesz podpisać plik przy użyciu dwóch metod:

Podpisywanie z szyfrowaniem

$ gpg --sign --output examples.sig examples.desktop 

You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28

gpg: Invalid passphrase; please try again ...

You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28

Jeśli jesteś na sesji komputerowej, prawdopodobnie zostaniesz powitany graficznym monitem o hasło. Na przykład w GNOME:

wprowadź opis zdjęcia tutaj

Jeśli odbiorca ma Twój klucz publiczny, może go zweryfikować lub uzyskać odszyfrowaną treść:

$ gpg --verify examples.sig
gpg: Signature made Monday 28 September 2015 03:25:00 PM IST using RSA key ID F7878B0C
gpg: Good signature from "Byte Commander <[email protected]>"
$ gpg --decrypt examples.sig
[Desktop Entry]
Version=1.0
Type=Link
Name=Examples
Name[aa]=Ceelallo
...
URL=file:///usr/share/example-content/
Icon=folder
X-Ubuntu-Gettext-Domain=example-content

gpg: Signature made Monday 28 September 2015 03:25:00 PM IST using RSA key ID F7878B0C
gpg: Good signature from "Byte Commander <[email protected]>"

Podpisywanie czystym tekstem

Możesz nie chcieć szyfrować zawartości, na przykład podczas wysyłania wiadomości e-mail. W takim przypadku skorzystaj z --clearsignopcji:

$ gpg --clearsign examples.desktop 

You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28

$ cat examples.desktop.asc 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

[Desktop Entry]
Version=1.0
Type=Link
Name=Examples
Name[aa]=Ceelallo
...
URL=file:///usr/share/example-content/
Icon=folder
X-Ubuntu-Gettext-Domain=example-content

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAEBAgAGBQJWCRAaAAoJEGUZkqX3h4sMBWsH/1yw+G0v5Ck+T3PBS90SkvC8
5C0FJeGVr0AgYQohhsE3zEGQ7nn53N7JsvNlF6VccvN99DZIp18JbrJ+qs5hWjtg
KU/ACleR5dvVrJgfjppkuC8Q3cAudvqciKlLjA7Xycr3P49oCNCy8k/ue2TrgCvS
mMb5IS/kqpO7wrOMBAR0c/2CjQsA91S1/YK7DbuUqeNgEzW1grsI7XZPhiDGpAib
D20HWrbdLhklAEJuo1EvuOIggW6MF6ksxDoVapsUzQalD0TWEq6OnvzIS5qhITrc
XaDPQJpiHyCyINnL5aZCUwr2uon7osJ+2a8Ahp1REpzIZTdND9jA5NWSel5+yAs=
=ZrtB
-----END PGP SIGNATURE-----

Podpisywanie za pomocą osobnego pliku do podpisu (odłączony podpis)

Wreszcie w przypadku niektórych plików podpis nie może mieć dokumentu. Na przykład pliki do pakowania lub metadane repozytorium zawierają treści o specyficznym charakterze, które nie pozwalają na łatwe osadzanie podpisów. W takim przypadku skorzystasz z --detached-sigopcji:

$ gpg --output examples.desktop.sig --detach-sign examples.desktop

You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28

$ gpg --verify examples.desktop.sig examples.desktop
gpg: Signature made Monday 28 September 2015 03:35:55 PM IST using RSA key ID F7878B0C
gpg: Good signature from "Byte Commander <[email protected]>"

Uwaga

W szyfrowaniu + podpisywaniu i odłączonych podpisach dane wyjściowe gpgsą binarne. Możesz mieć wyjściowe dane GnuPG zakodowane w base64, korzystając z --armoropcji (opancerzone ASCII).

Automatyzacja

Aby podpisać skrypt, możesz:

muru
źródło
Bardzo miła i szczegółowa odpowiedź. Ale o przykładowych kluczach, które utworzyłeś ... Nie wiem, czy jestem zbyt szczęśliwy z faktu, że leżą w nim nieużywane klucze do mojego pseudonimu. Jeśli chcę później stworzyć prawdziwe klucze o tej nazwie i użyć ich, ludzie szukający ich mogą się pomylić. Sądzę, że twoje przykładowe klucze i moje prawdziwe klucze będą mogły współistnieć z powodu różnych adresów e-mail i dlatego uzyskają inny identyfikator, ale nadal ... Czy to możliwe, że możesz je ponownie usunąć?
Bajt Dowódca
@ByteCommander terminu jest revoke . Spróbuję je odwołać. W tym celu powinienem dodać sekcję dotyczącą odwoływania kluczy.
muru
@ByteCommander przepraszam, usunąłem klucz, który opublikowałem (i nie popełniłem certyfikatu odwołania (klasyczny błąd n00b), więc nie mogę odwołać tego klucza. Jednak upływa on rok, więc cóż, wszelkie nieporozumienia zostaną rozwiązane za rok
muru
Okej, cóż - tak się dzieje. Nie jestem pewien, czy powinienem być zirytowany, czy po prostu śmiać się z tej głupiej pomyłki ... Myślę, że w przypadku mojego projektu wolę po prostu użyć modułu Python, rsaktóry z łatwością pozwala podpisywać dane bez zmagania się z wszystkimi rzeczami związanymi z GPG. Może się to bardzo przydać, gdy zacznę naprawdę publikować i pakować oprogramowanie, ale w tej chwili jest to prawdopodobnie zbyt wiele do moich celów. Do tego czasu prawdopodobnie wygasnie! :)
Byte Commander
@ByteCommander oba, jak sądzę. Chociaż sugerowałbym, abyś używał swojego prawdziwego imienia i nazwiska podczas tworzenia klucza i pozostawił nick w polu komentarza.
muru
4
  1. Utwórz asymetryczny klucz za pomocą gpg

    gpg --gen-key
    
  2. Użyj gpg do podpisania pliku (używany jest klucz prywatny)

    gpg --output foo.sig --detach-sig foo.py
    
  3. Przetestuj plik podpisu (używany jest klucz publiczny)

    gpg --verify foo.sig foo.py
    

    Przykładowe dane wyjściowe

    % gpg --verify foo.sig foo.py 
    gpg: Signature made Mo 28 Sep 2015 12:46:04 CEST using RSA key ID 89B30DEC
    gpg: Good signature from "Your Name <[email protected]>"
    
    % echo "bad" >> foo.py
    
    % gpg --verify foo.sig foo.py
    gpg: Signature made Mo 28 Sep 2015 12:46:04 CEST using RSA key ID 89B30DEC
    gpg: BAD signature from "Your Name <[email protected]>"
    
AB
źródło