zu IT-Sicherheit und mehr

PGP Schlüssel generieren wie ein Experte

von

in

Kategorie:

Verschlüsselung; Public Domain; openclipart.org
Verschlüsselung; Public Domain; openclipart.org

Im heutigen Beitrag geht es etwas erweitert daher, und die Zielgruppe sind diejenigen, die bereits PGP nutzen, oder das Basiswissen erweitern möchten.

Normalerweise, wenn Sie einen Schlüssel generieren, erhalten Sie standardmässig einen RSA Schlüsselpaar (meistens mit einer Länge von 2048 oder 4096 Bits), wobei der Hauptschlüssel zertifizieren und signieren kann, und ein separater Unterschlüssel für die Verschlüsselung generiert wird. Standardmässig laufen keine der Schlüssel ab.

Wir können das jedoch optimieren!

Ich muss aber klar bemerken, dass es hier nicht um eine 08/15 Anwendung von PGP geht, sondern um eine erweiterte Anwendung, die für die meisten Menschen vermutlich eher als «unpraktisch» empfunden wird. Wer jedoch interessiert daran ist, zu wissen, wie es theoretisch gehen könnte, oder meint dies zu benötigen, darf gerne weiterlesen. Ich habe euch aber gewarnt! 🙂

Schauen wir uns die Punkte etwas genauer an:

RSA und Curve25519

RSA wird mittlerweile langsam durch elliptische Kurven wie z.B. Curve25519 abgelöst.

Den Algorithmus zu erklären, wäre für diesen Beitrag etwas zu viel, aber einen kurzen Überblick: Beide Verfahren nutzen natürlich ein unlösbares Problem in der Mathematik. Bei RSA geht es um Primzahlen, und bei Curve25519 um elliptische Kurven. Wobei die einzige «Lösung» den privaten Schlüssel ausfindig zu machen, im «ausprobieren bis gefunden» besteht, was mit heutiger Technik «endlos» dauern würde.

Das Interessante jedoch: Schlüssel mit Curve25519 sind immer 256-Bit lang. Was aber wichtig ist zu verstehen: 256-Bit Curve25519 Schlüssel sind nicht weniger sicher, nur weil sie kürzer sind! Es ist eine ganz andere Problemstellung, und ein direkter Vergleich ist schwierig, aber grob gesagt, Curve25519 mit 256-Bit, hat etwa die Stärke von RSA mit 3072-Bit. Beides gilt heutzutage als sicher.

Beide Verfahren sind natürlich sinngemäss rechenaufwendig, elliptische Kurven sind jedoch «leichter», wenn der Schlüssel bekannt ist. Das macht Curve25519 somit schneller, womit es für schwächere Hardware besser geeignet ist. Bemerkbar macht sich dies teilweise z.B. mit einem Hardware-Sicherheitsschlüssel, wobei der mit RSA Schlüssel vergleichbarer Stärke, deutlich mehr rechnen muss.

RSA hat den klaren Vorteil, alt zu sein, also sprich: Weiter verbreitet, besser unterstützt, erweiterte Kompatibilität. Wer z.B. seinen PGP Schlüssel mit Curve25519 auf seinen YubiKey laden möchte, braucht dafür mindestens einen YubiKey 5, mit Firmware Version 5.2 oder neuer (verfügbar seit ca. Ende 2020).

Es ist natürlich unmöglich in die Zukunft zu sehen, aber ich behaupte jetzt einfach mal, dass elliptische Kurven, zumindest vorerst, die nahe Zukunft sind, und wir werden somit spezifisch auf Curve25519 setzen.

Subkeys (Unterschlüssel)

Wie zuvor erwähnt, wird standardmässig ein Hauptschlüssel generiert, der zertifizieren und signieren kann, mit einem Unterschlüssel für die Verschlüsselung.

Der Nachteil dabei: Wenn der Schlüssel abhandenkommt, muss der widerrufen werden, ihr müsst einen neuen Schlüssel generieren, den mit allen euren Kontakten teilen, und den Fingerabdruck neu verifizieren lassen. Das ist aufwendig und kann vermieden werden!

Stattdessen empfehle ich einen Hauptschlüssel zu generieren, der nur zertifizieren kann, und drei Unterschlüssel zu generieren, und zwar je einen für Verschlüsselung, Signatur und Authentifizierung (kann z.B. für SSH verwendet werden).

Der Hauptschlüssel wird dann nur noch für Änderungen am Schlüsselpaar genutzt, wie z.B. das Ändern von Ablaufdaten, Erstellung oder Widerrufung von Unterschlüsseln, das Hinzufügen von Identitäten, usw. Der Trick dabei: Der Hauptschlüssel wird sicher offline aufbewahrt (z.B. auf mehrere USB-Sticks verschlüsselt abgespeichert, und in einen Brandschutzsafe, Bankschliessfach, oder realistischer «in der einen Schublade mit Krimskrams» usw.) und dann vom Computer gelöscht. Ihr nutzt dann nur noch die Unterschlüssel für alltägliche Aufgaben, und holt den Hauptschlüssel nur hervor, wenn ihr was am Schlüsselpaar ändern müsst.

Wenn die Unterschlüssel kompromittiert wurden, holt ihr den Hauptschlüssel hervor (auf einem sauberen Gerät), widerruft einfach die Unterschlüssel, generiert neue, und verteilt den neuen öffentlichen Schlüssel. Das Gute daran: Der Fingerabdruck ist unverändert. Der stammt nämlich vom Hauptschlüssel, welcher jedoch nicht kompromittiert wurde, da der zum Zeitpunkt des «Vorfalls» nicht auf dem Computer vorhanden war.

Das ist eigentlich die «korrekte» Art der Schlüsselverwaltung. Warum dies nicht Standard ist, kann ich nicht sagen. Meine Vermutung: Es ist für die meisten einfach zu aufwendig, eine Zertifizierungsstelle zu spielen. Für Endverbraucher ist ja schon die «normale» Art von PGP zu viel.

Tipp: Ihr müsst den USB-Stick nicht separat verschlüsseln, einfaches FAT32 oder exFAT reicht aus, denn, sofern Ihr ein Passwort definiert habt, wird der Schlüssel verschlüsselt abgespeichert. Bedenkt einfach, dass das Passwort stark sein muss, denn es ist das Einzige, was den Schlüssel beschützt. Ich empfehle jedoch ein robusteres Dateisystem, je nachdem, was Ihr für ein Betriebssystem nutzt.

Ablaufdatum

Es ist «best practice» Schlüsseln immer ein Ablaufdatum zu vergeben. Das hat auch praktische Gründe: Ich habe es schon oft gesehen, dass einige ein Schlüsselpaar generierten, und dann den Schlüssel verloren. Wenn dann kein Widerrufs-Zertifikat existiert, bleibt der Schlüssel gültig, auch wenn nicht mehr nutzbar. Wenn der Schlüssel dann auf einem altmodischen Schlüsselserver ist (nicht empfohlen), wo der Schlüssel nicht gelöscht werden kann, wird man weiterhin E-Mails erhalten, die nicht geöffnet werden können. Das Einzige, was euch dann noch rettet, ist ein Ablaufdatum. Es ist nämlich immer möglich, das Ablaufdatum eines vorhandenen Schlüssels zu verlängern, nicht jedoch umgekehrt.

Meine Empfehlung, als Richtlinie, die Ihr anpassen könnt: dem Hauptschlüssel eine Lebensdauer von 5 Jahren zuweisen, und den Unterschlüsseln jeweils ein Jahr. Dann, einmal jährlich, holt ihr den Hauptschlüssel hervor, und rotiert die Unterschlüssel. Das bedeutet, neue Unterschlüssel generieren (1 Jahr), und die alten ablaufen lassen, und evtl. auf einen USB-Stick verschieben. Falls die Schlüssel abhandenkommen, werden somit höchstens 1 Jahr an E-Mails entschlüsselbar. Falls ihr oft auf alte E-Mails zugreift, könnt ihr die Schlüssel auch auf dem Rechner lassen, geniesst aber nicht den erweiterten Schutz.

Wer YubiKeys nutzt, aber auch oft alte E-Mails öffnen muss, der muss stattdessen einfach das Ablaufdatum der Unterschlüssel verlängern. Das liegt daran, dass YubiKeys nur drei Keyslots haben, und ältere Unterschlüssel somit nicht draufpassen. Der Vorteil jedoch ist: Die Schlüssel können nicht ausgelesen werden, die Gefahr der Kompromittierung ist also gering (der Angreifer müsste an den YubiKey sowie die PIN gelangen, Malware kann den Schlüssel nicht auslesen).

Zwischenbemerkung

So, bald werden wir gemeinsam ein Schlüsselpaar generieren. Ich möchte aber klar betonen: Was ich hier beschreibe, ist nicht die übliche Art PGP zu nutzen, und für die meisten ist es unpraktisch und ohne grossen Gewinn. Wenn ihr aber James Bond spielen wollt, lest weiter.

Generierung der Schlüssel à la James Bond

Wir werden GnuPG (gpg) im Terminal verwenden. Ich nutze für dieses Beispiel GnuPG/MacGPG2 Version 2.2.41.

Wir werden GnuPG im Expertenmodus starten:

gpg --full-gen-key --expert

Folgendes ist zu sehen:

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)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
   (9) ECC and ECC
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (13) Existing key
  (14) Existing key from card
Your selection?

Wir wählen 11, um unsere eigenen Angaben … anzugeben. 😄

Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Sign Certify

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection?

Wir sehen nun, dass der Schlüssel momentan «Sign» und «Certify» kann. Wir wollen aber nur Zertifizierung, geben also «S» ein, um «Sign» zu deaktivieren. Wir sollten nun nur noch «Certify» sehen, und geben somit «Q» ein, um zu beenden.

Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection?

Wir wollen Curve25519, und geben somit 1 ein.

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)

Da es sich hierbei um den Hauptschlüssel geht, wollen wir, dass der in 5 Jahren abläuft und geben somit «5y» ein, überprüfen das Ablaufdatum, und wenn alles korrekt ist, bestätigen wir mit «y».

GnuPG needs to construct a user ID to identify your key.

Real name:

So, jetzt werdet Ihr drei Fragen gestellt. Ihr müsst euren Namen eingeben (das muss nicht der rechtliche Name sein!), mit Enter bestätigen, dann die E-Mail-Adresse, erneut mit Enter bestätigen, und zuletzt noch einen Kommentar, den ihr auslassen könnt, und erneut mit Enter bestätigen. Am Ende wird euch die «USER-ID» angezeigt, wenn alles gut aussieht, bestätigt ihr mit dem Buchstaben «O».

Nun müsst ihr ein Passwort eingeben, womit der Schlüssel geschützt wird. Ihr müsst euch dieses Passwort gut merken, oder noch besser, zufällig generieren und im Passwortmanager abspeichern.

Der Hauptschlüssel ist nun generiert! Ihr solltet auch gleich Infos dazu angezeigt bekommen:

gpg: revocation certificate stored as '/Users/nat/.gnupg/openpgp-revocs.d/9F67C23D80C185EAD0B99A4C5BF2C3D0C08EA34F.rev'
public and secret key created and signed.

pub   ed25519/0x5BF2C3D0C08EA34F 2023-09-02 [C] [expires: 2028-08-31]
      Key fingerprint = 9F67 C23D 80C1 85EA D0B9  9A4C 5BF2 C3D0 C08E A34F
uid                              Natalie Kagelmacher <+@kagel.ch>

Ihr seht da «revocation certificate», am besten gleich die Datei in den Passwortmanager und/oder auf USB-Sticks. Das ist das Widerrufs-Zertifikat, wenn der Schlüssel abhandenkommen sollte (damit könnt ihr den Schlüssel als ungültig erklären).

Das wird übrigens auch gleich mein echter neuer Schlüssel, ich habe jedoch den Benutzernamen vor dem @ mit einem Plus ersetzt, wegen Spambots. Es ist jedoch in Wirklichkeit «nat». 😉

So, jetzt geht es aber noch weiter … ziemlich mühsam!

gpg --edit-key --expert +@kagel.ch

Mit diesem Befehl editieren wir den Schlüssel, um Unterschlüssel zu erstellen. Ersetzt die E-Mail-Adresse natürlich mit der eigenen.

Ihr solltet nun in einem interaktiven Modus sein. Gebt «addkey» ein und bestätigt mit Enter. Wir geben wieder 11 ein, und sollten nun auswählen können, was wir möchten. Wir sollten «Sign» sehen, und bestätigen somit mit Q, und wählen 1 für Curve25519, geben 1y für das Ablaufdatum ein, bestätigen mit y, dann nochmal y, geben das bestehende Passwort ein, geben «save» ein, um den Fortschritt nicht zu verlieren. Nun rufen wir wieder den --edit-key Befehl ein, und machen das Ganze erneut, aber diesmal für Encrypt und Authenticate (also nicht immer die Option 11!). Das Ganze sieht in etwa so aus:

❯ gpg --edit-key --expert +@kagel.ch
gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection? 11

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1
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 Sun Sep  1 06:28:46 2024 CEST
Is this correct? (y/N) y
Really create? (y/N) y
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, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  ed25519/0x5BF2C3D0C08EA34F
     created: 2023-09-02  expires: 2028-08-31  usage: C
     trust: ultimate      validity: ultimate
ssb  ed25519/0x2B31C35FF98972EE
     created: 2023-09-02  expires: 2024-09-01  usage: S
[ultimate] (1). Natalie Kagelmacher <+@kagel.ch>

gpg> save

❯ gpg --edit-key --expert +@kagel.ch
gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection? 12
Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1
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 Sun Sep  1 06:33:48 2024 CEST
Is this correct? (y/N) y
Really create? (y/N) y
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, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  ed25519/0x5BF2C3D0C08EA34F
     created: 2023-09-02  expires: 2028-08-31  usage: C
     trust: ultimate      validity: ultimate
ssb  ed25519/0x2B31C35FF98972EE
     created: 2023-09-02  expires: 2024-09-01  usage: S
ssb  cv25519/0xB04C0BF9FC8DF669
     created: 2023-09-02  expires: 2024-09-01  usage: E
[ultimate] (1). Natalie Kagelmacher <+@kagel.ch>

gpg> save

❯ gpg --edit-key --expert +@kagel.ch
gpg> addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
  (10) ECC (sign only)
  (11) ECC (set your own capabilities)
  (12) ECC (encrypt only)
  (13) Existing key
  (14) Existing key from card
Your selection? 11

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions: Sign

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? s

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions:

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? a

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions: Authenticate

   (S) Toggle the sign capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q
Please select which elliptic curve you want:
   (1) Curve 25519
   (3) NIST P-256
   (4) NIST P-384
   (5) NIST P-521
   (6) Brainpool P-256
   (7) Brainpool P-384
   (8) Brainpool P-512
   (9) secp256k1
Your selection? 1
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 Sun Sep  1 06:34:23 2024 CEST
Is this correct? (y/N) y
Really create? (y/N) y
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, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  ed25519/0x5BF2C3D0C08EA34F
     created: 2023-09-02  expires: 2028-08-31  usage: C
     trust: ultimate      validity: ultimate
ssb  ed25519/0x2B31C35FF98972EE
     created: 2023-09-02  expires: 2024-09-01  usage: S
ssb  cv25519/0xB04C0BF9FC8DF669
     created: 2023-09-02  expires: 2024-09-01  usage: E
ssb  ed25519/0xDC9F9AAE257CDF7D
     created: 2023-09-02  expires: 2024-09-01  usage: A
[ultimate] (1). Natalie Kagelmacher <+@kagel.ch>

gpg> save

Wenn ihr am Ende vier Schlüssel habt, mit jeweils C, S, E und A, habt ihr alles richtig gemacht!

Schlüssel sichern und löschen

Aber, ich habe euch gewarnt. Wir sind noch nicht fertig!

Nun machen wir Backups von den Schlüsseln. Einmal komplett, und einmal nur die Subkeys. Beide Backups kommen ebenfalls auf den USB-Stick. Dann löschen wir den Schlüssel vom Rechner, und importieren nur die Subkeys wider rein. Wer einen YubiKey nutzen möchte, würde danach die Subkeys auf den YubiKey verschieben.

Schauen wir mal den bestehenden Schlüssel an:

gpg -k +@kagel.ch
pub   ed25519/0x5BF2C3D0C08EA34F 2023-09-02 [C] [expires: 2028-08-31]
      Key fingerprint = 9F67 C23D 80C1 85EA D0B9  9A4C 5BF2 C3D0 C08E A34F
uid                   [ultimate] Natalie Kagelmacher <+@kagel.ch>
sub   ed25519/0x2B31C35FF98972EE 2023-09-02 [S] [expires: 2024-09-01]
sub   cv25519/0xB04C0BF9FC8DF669 2023-09-02 [E] [expires: 2024-09-01]
sub   ed25519/0xDC9F9AAE257CDF7D 2023-09-02 [A] [expires: 2024-09-01]

Nun machen wir Backups:

❯ gpg --export-secret-keys -a +@kagel.ch > PRIVATE_COMPLETE_+@kagel.ch.asc
❯ gpg --export-secret-subkeys -a +@kagel.ch > PRIVATE_SUBKEYS_+@kagel.ch.asc
❯ gpg --export -a +@kagel.ch > PUBLIC_+@kagel.ch.asc

Nachdem die Schlüssel mehrmals auf USB-Sticks gesichert sind, löschen wir sie vom GnuPG Schlüsselbund:

gpg --delete-secret-keys +@kagel.ch

Ihr werdet mehrmals gefragt, und ihr müsst mehrmals bestätigen. Das ist quasi die Plastik-Schutzkappe, bevor ihr auf den grossen roten Knopf hauen könnt.

Nun importieren wir die Subkeys:

gpg --import PRIVATE_SUBKEYS_+@kagel.ch.asc

Wenn Ihr nun erneut gpg -k +@kagel.ch eingebt, kann es sein, dass ihr vor dem Hauptschlüssel ein # steht. Dies bedeutet, der Hauptschlüssel ist nicht im Schlüsselbund, das ist korrekt so. In meinem Falle wird dies im Terminal nicht dargestellt, jedoch im GUI sehe ich neben «Card» nun ein «#».

Wir sind nun eigentlich fertig!

Wer noch weitergehen will, verschiebt die Schlüssel auf einen YubiKey oder ähnlich, wieder mit dem --edit-key Befehl, aber diesmal anstelle von «addkey» gebt ihr «keytocard» ein und befolgt die Schritte. Am besten im Herstellerhandbuch eures spezifischen Hardware-Schlüssels nachschlagen, wie ihr dies am besten macht.

SSH

Euer SSH public key erhält ihr übrigens so (mit eurer Adresse ersetzen):

gpg --export-ssh-key +@kagel.ch

Wie ihr GnuPG als SSH Agent nutzt, ist ein Thema für ein anderes Mal.

Fazit

Sofern ihr dem Artikel nachgegangen seid, habt ihr möglicherweise, das bestmögliche PGP Setup. Es ist nicht wirklich realistisch, ich hoffe jedoch sehr, es hat trotzdem irgendwie weitergeholfen oder war zumindest Spass! 😊

Diesen Artikel zu verfassen, hat unerwartet doch noch mehrere Stunden gedauert. Es ist immer wieder erstaunlich wie leicht es ist dies zu unterschätzen! Ich frage mich, ob ich so ein Ko-fi einrichten soll. Einen Kaffee könnte ich nun nämlich wirklich gebrauchen. 😅☕️


Lernen Sie die verschiedene Wege kennen, meinem Blog zu Folgen!


2 Antworten zu “PGP Schlüssel generieren wie ein Experte”

  1. @nat Das habe ich jetzt mal so umgesetzt und die Keys mit dem `keytocard` Befehl auf meinen Hardware-Key verschoben. Der hat Slots für Signatur, Encryption und Authentication, wobei der Signaturschlüssel in meinem Fall noch zertifizieren darf. Die haben aber unterschiedliche Fingerprints. Das heißt, wenn ich eine Mail signieren will, muss der Empfänger einem anderen Key vertrauen als wenn ich eine Mail verschlüssele, nicht wahr?

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert