Wie signiere ich Dateien mit Ubuntu-Befehlszeilentools und meinen eigenen Schlüsseln?

14

Ich möchte einige von mir geschriebene Python-Codedateien signieren, da es sich um Plug-in-Module für eines meiner Projekte handelt. Zum Verteilen möchte ich, dass der Benutzer sicher sein kann, dass ein Plug-in verifiziert und sicher ist (weil es von mir oder von jemandem geschrieben wurde, dem ich vertraue) und nicht geändert wurde.

Die Software ist nur ein Open-Source-Hobbyprojekt, daher möchte ich kein Geld für den Kauf eines offiziellen Zertifikats ausgeben. Stattdessen gehe ich davon aus, dass das Hauptprogramm immer gültig ist und ohne zusätzliche Überprüfung vertrauenswürdig ist. Wenn jemand es von einem anderen Ort als meinem GitHub-Repository herunterlädt, ist dies seine Schuld.

Nach dem, was ich gelesen habe, erfolgt das Signieren normalerweise durch Erstellen eines asymmetrischen Schlüsselpaars, Berechnen eines starken kryptografischen Hashwerts (z. B. SHA-512) aus der Codedatei, Verschlüsseln des Hashs mit meinem privaten Schlüssel und Speichern dieser Signatur in einer separaten Datei mit der Original-Code-Datei geliefert werden.
Das Hauptprogramm muss dann die Signatur mit dem öffentlichen Schlüssel entschlüsseln, der im Quellcode des Hauptprogramms im Klartext gespeichert ist, die gleiche Hash-Funktion der Codedatei berechnen und mit der entschlüsselten vergleichen. Wenn sie übereinstimmen, kann das Plug-In als vertrauenswürdig eingestuft werden.

Also jetzt meine Frage:

Wie erstelle ich mit Ubuntu-Tools auf einfache Weise ein stark asymmetrisches Schlüsselpaar und wie berechne ich auf einfache Weise einen kryptografischen Hashwert einer Datei?
Das Automatisieren des Signaturprozesses in einem Skript (unter Verwendung immer desselben Schlüssels) wäre großartig.

Byte Commander
quelle

Antworten:

19

Ein Großteil dieser Antwort stammt aus dem Arch Wiki und der GnuPG-Dokumentation . Alle Empfehlungen in dieser Antwort sind rein meine Meinung und sollten mit einer Tonne Salz genommen werden.

PGP-Schlüssel erstellen

GUI

  1. Öffnen Sie die App Passwörter und Schlüssel (aka seahorse) und klicken Sie auf +(oder gehen Sie zu Datei -> Neu oder drücken Sie CtrlN), um Folgendes anzuzeigen:

    Neuer Itemdialog für Seahorse

  2. Wählen Sie den PGP-Schlüssel und geben Sie Ihre Daten ein. Ich verkörpere Byte Commander:

    Schlüsseldetails-Dialog

    RSA und 2048 Bits sind für die meisten Zwecke ausreichend. Wenn Sie es nur zum Signieren verwenden möchten, wählen Sie im Dropdown-Menü die Option RSA (nur Signieren) aus. Dies sollte jedoch nicht erforderlich sein. Dies kann mithilfe von Unterschlüsseln erfolgen . Sie können einen Kommentar hinterlassen. Das Verfallsdatum Ihres Schlüssels beizubehalten ist ebenfalls nützlich. Klicken Sie auf Create.

  3. Geben Sie ein entsprechend langes Passwort ein (und ich meine lang , mein Beispiel ist kurz, IMO) und klicken Sie auf Ok:

    Passwort-Eingabedialog

    Seahorse scheint im Gegensatz zur CLI kein Feedback zu haben. Warten Sie eine Weile und tun Sie, was Sie wollen, während Entropie gesammelt und ein Schlüssel erstellt wird. Es könnte eine Weile dauern. Danach werden sie im Abschnitt PGP-Schlüssel angezeigt:

    Liste der PGP-Schlüssel

CLI

Führen Sie einfach aus, um einen Schlüssel über die Befehlszeile zu generieren gpg --gen-key. Sie werden nach denselben Details gefragt, die die GUI vorgenommen hat:

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

Beachten Sie, wie GnuPG uns sagt, dass es mehr Entropie benötigt. Ich wünschte, Seepferdchen auch. Andererseits scheint GnuPG sich wie Oliver Twist zu verhalten. : P

Veröffentlichen Sie Ihren Schlüssel

Jetzt müssen wir unseren öffentlichen Schlüssel herausbringen, damit die Leute die Dinge damit überprüfen können.

GUI

Kehren Sie zur Liste der PGP-Schlüssel in der seahorseApp zurück (siehe letzter Screenshot). Wählen Sie die Schlüssel aus, die Sie exportieren möchten, und wählen Sie im Menü Remote die Option Schlüssel synchronisieren und veröffentlichen :

Bildbeschreibung hier eingeben

Die SyncSchaltfläche wird deaktiviert, wenn Sie keinen Server zum Veröffentlichen ausgewählt haben. Klicken Sie dazu auf die Key ServersSchaltfläche:

Bildbeschreibung hier eingeben

Ich habe Ubuntus Server ausgewählt.

Jetzt können Sie auf die SyncSchaltfläche klicken und sie auf Ubuntus Keyserver veröffentlichen lassen (Entschuldigung für den Spam, Ubuntu!).

CLI

Mit der CLI benötigen Sie die Schlüssel-ID des Schlüssels, den Sie veröffentlichen möchten. Dies ist die allerletzte Zeile der Ausgabe beim Erstellen des Schlüssels ( 8AE670A6). Wenn Sie sich nicht erinnern, was es ist, laufen Sie einfach gpg --list-keys. Veröffentlichen:

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

Entschuldigung, MIT .

Unterzeichnung

Ich kenne noch keine bequeme GUI-Methode zum Signieren eines Dokuments.

Sobald Sie die zu signierende Datei erstellt haben, begeben Sie sich zum Terminal. Versuchen Sie 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]

Sie können die Datei auf zwei Arten signieren:

Mit Verschlüsselung signieren

$ 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

Wenn Sie sich in einer Desktopsitzung befinden, werden Sie wahrscheinlich mit einer grafischen Kennwortabfrage begrüßt. Zum Beispiel in GNOME:

Bildbeschreibung hier eingeben

Wenn der Empfänger über Ihren öffentlichen Schlüssel verfügt, kann er diesen überprüfen oder den entschlüsselten Inhalt abrufen:

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

Unterschreiben mit Klartext

Möglicherweise möchten Sie den Inhalt nicht verschlüsseln, wenn Sie beispielsweise eine E-Mail senden. In diesem Fall verwenden Sie die --clearsignOption:

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

Unterschreiben, mit einer separaten Datei zur Unterschrift (getrennte Unterschrift)

Schließlich können Sie für einige Dateien die Signatur nicht im Dokument haben. Beispielsweise haben Paketdateien oder die Metadaten für ein Repository bestimmte Inhalte, die eingebettete Signaturen nicht einfach zulassen. In diesem Fall verwenden Sie die --detached-sigOption:

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

Hinweis

Bei Verschlüsselung + Signieren und getrennten Signaturen ist die Ausgabe von gpgbinär. Sie können GnuPG Base64-codierte Daten mit der --armorOption (ASCII-gepanzert) ausgeben lassen .

Automatisierung

Um ein Skript zu signieren, können Sie:

muru
quelle
Sehr nette und ausführliche Antwort. Aber zu den Beispielschlüsseln, die Sie erstellt haben ... Ich weiß nicht, ob ich zu glücklich darüber bin, dass ein Satz nicht verwendeter Schlüssel für mein Pseudonym herumliegt. Wenn ich später echte Schlüssel mit diesem Namen erstellen und verwenden möchte, sind die Leute, die danach suchen, möglicherweise verwirrt. Ich vermute, Ihre Beispielschlüssel und meine echten Schlüssel können aufgrund unterschiedlicher E-Mail-Adressen nebeneinander existieren und erhalten daher eine andere ID, aber dennoch ... Können Sie diese Schlüssel möglicherweise wieder löschen?
Byte Commander
@ByteCommander Der Begriff wird widerrufen . Ich werde versuchen, sie zu widerrufen. In diesem Fall sollte ich einen Abschnitt zum Widerrufen von Schlüsseln hinzufügen.
muru
@ByteCommander Entschuldigung, ich habe den veröffentlichten Schlüssel gelöscht (und kein Widerrufszertifikat ausgestellt (klassischer Fehler bei n00b)), daher kann ich diesen Schlüssel nicht widerrufen. Er hat jedoch einen Ablauf von einem Jahr. Verwirrung wird in einem Jahr
behoben sein
Okay, das passiert. Ich bin mir nicht sicher, ob ich mich ärgern oder nur über diesen dummen Fehler lachen soll ... Ich denke, für mein fragliches Projekt verwende ich lieber nur das Python-Modul, mit rsadem sich Daten problemlos signieren lassen, ohne mit all dem GPG-Zeug zu kämpfen. Das kann sehr nützlich sein, wenn ich erst einmal anfange, Software zu veröffentlichen und zu verpacken, ist aber im Moment wahrscheinlich einfach zu viel für meinen Zweck. Bis dahin ist es also wahrscheinlich abgelaufen! :)
Byte Commander
@ByteCommander beide, nehme ich an. Obwohl ich vorschlagen würde, dass Sie beim Erstellen Ihres Schlüssels Ihren richtigen Namen verwenden und den Nick für das Kommentarfeld belassen.
muru
4
  1. Erstellen Sie mit gpg einen asymmetrischen Schlüssel

    gpg --gen-key
    
  2. Verwenden Sie gpg, um Ihre Datei zu signieren (Ihr privater Schlüssel wird verwendet)

    gpg --output foo.sig --detach-sig foo.py
    
  3. Testen Sie die Signaturdatei (Ihr öffentlicher Schlüssel wird verwendet)

    gpg --verify foo.sig foo.py
    

    Beispielausgabe

    % 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
quelle