eToken und GPG-Key

eToken und GPG-Key

17. Mai 2023·me
me

Ich nutze den GPG-Key für folgende Funktionen:

  • SSH-Key (gpg-agent und unter Android TermBot der OpenKeyChain Support wurde ersetzt, Gründe gab es mal wurden von der Webseite entfernt)
  • Password-Manager pass (in Firefox mit browserpass auf Android mit Password Store und OpenKeychain)
  • gelegentlich E-Mails

Dieser Artikel soll allerdings nicht den Einsatz beschreiben, sondern die Einrichtung auf ein eToken. Für die Einrichtung nutze ich ein yubiKey, doch dies sollte einfach für ein NitroKey funktionieren, was ich villt. nachhole.

1. Generierung von Schlüsseln

Wo wird / Sollte der Schlüssel generiert werden

Mit dem Spruch “kein Backup kein Mitleid”, muss zunächst die Schlüssel auf ein Rechner generiert werden (und im 3. Schritt auf den eToken übertragen). Im Allgemeinen gilt, das die meisten eTokens selbst Schlüssel-Generatoren besitzen. Vorteil: Die privaten Schlüssel, nie ein Rechner, der möglicherweise Infiziert ist, betrehten und auf Hardwareebene vorm Auslesen geschützt sind. Nachteil: Der eToken kann ausversehen (oder mit Absicht) zerstört, verloren, geklaut werden und somit den privaten Schlüssel. Wenn dieser private Schlüssel die einziege Zugangsmöglichkeit ist / werden soll, schliest man sich ggf. selbst aus. PS: Natürlich ist es möglich mehrere GPG- und SSH-Keys in den meisten Systemen zu hinterlegen.

Zudem sollten mal bevor man eine Entscheidung trifft, sich auch den Zufallszahlen-Generator anschauen. Auf ein Rechner lässt sich eher den aktuelle Version eines Generators verwenden, als das er im Hardware-Token ausgetausch wird (wobei dies auch durch Firmware-Updates je nach hersteller möglich ist). In der Vergangenheit wurden natürlich auf beiden Seiten (Kernel und eToken-Chips) festgestellt, das die Zufallszahlen nicht ganz so zufällig waren.

Ein Unternehmen, für das ich tätig war, hat ganz kurz bei dieser Nachricht geschwitzt gehabt:

PS: Es ist auch bekannt, das Geheimdienste versuchen schwache oder pseudo Zufallszahlengenerator: https://www.heise.de/news/NSA-Affaere-Generatoren-fuer-Zufallszahlen-unter-der-Lupe-1953716.html

PSS: Pseudo-Generatoren sind generelle Sinnvoll, wenn es um kurzlebige Schlüssel geht und diese von ein “sicheren” Schlüssel abgeleitet werden (z.B. OTP).

Kurz:

Schlüsselverfahren und -länge

Je länger desto sicherer, …

Quanten-Computer

Hier ein netter Vortrag, auch wenn von ein CIS-Mann oft unterbrochen über Quanten-Sichere Kryptographie in VPN-Software Rosenpass. Aktuelle ist es mir nicht bekannt, das es ein einheitlichen weltweiten Standard oder ein Hersteller von eToken die Quantensicher sind gibt. Daher betrachte ich aktuelle noch nicht dieses Problem in meiner Umsetzung (auch wenn ich mich weiter informiere und über informationen mich freue).

GPG-Befehle

Nun lege ich los. Ich hab mich für ein ED25519 - Elliptic Curve Cryptography entschieden, denn ich einmal im Jahr verlängere. Diesen werde ich auf mein Rechner (der frisch aufgesetzt wurde und die aktuellen Softwareversionen besitzt).

Bei den folgenden zwei Befehlen werden wir nach ein Passphrase gefragt, diese

# gpg --full-generate-key
gpg (GnuPG) 2.4.0; Copyright (C) 2021 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
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
   (9) ECC (sign and encrypt) *default*
  (10) ECC (sign only)
  (14) Existing key from card
Your selection? 
Please select which elliptic curve you want:
   (1) Curve 25519 *default*
   (4) NIST P-384
   (6) Brainpool P-256
Your selection? 
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 Thu 16 May 2024 11:22:03 CEST
Is this correct? (y/N) y

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

Real name: WrenIX
Email address: dev@wrenix.eu
Comment: 
You selected this USER-ID:
    "WrenIX <dev@wrenix.eu>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
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.
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.
gpg: directory '/home/wrenix/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/wrenix/.gnupg/openpgp-revocs.d/B9C35FDD7362F063A8706A2E7AFDB012974B1BB5.rev'
public and secret key created and signed.

pub   ed25519/0x7AFDB012974B1BB5 2023-05-17 [SC] [expires: 2024-05-16]
      Key fingerprint = B9C3 5FDD 7362 F063 A870  6A2E 7AFD B012 974B 1BB5
uid                              WrenIX <dev@wrenix.eu>
sub   cv25519/0x4964120E6A1FB3D4 2023-05-17 [E] [expires: 2024-05-16]

Nun haben wir bereits ein Key zum Signieren und ein zum Verschlüsseln, zuletzt brauchen wir noch ein zum Authentifizieren (z.B. für SSH).

# gpg2 --expert --edit-key dev@wrenix.eu 
gpg (GnuPG) 2.4.0; Copyright (C) 2021 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.

Secret key is available.

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
[ultimate] (1). WrenIX <dev@wrenix.eu>

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 this ECC 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 this ECC key: Sign Authenticate 
Current allowed actions: 

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

Your selection? A

Possible actions for this ECC 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 *default*
   (2) Curve 448
   (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 Thu 16 May 2024 11:33:00 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/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> save

Nun haben wir die drei benötigten Schlüssel, die wir einzeln in die drei Smartcard-Slots im eToken (yubiKey) übertragen werden, nachdem wir ein Backup der Keys gemacht haben.

2. Backup von Schlüsseln

Während der Schlüsselgenerierung wurde ein sogennanten RevokeKey schon gebackuped, diese Speichern wir ebenfalls in unser Backup:

# backup from revoke key
mv ~/.gnupg/openpgp-revocs.d/B9C35FDD7362F063A8706A2E7AFDB012974B1BB5.rev .
# backup from privaten schluessel
gpg2 --armour -o dev@wrenix.eu.private.gpg --export-secret-keys B9C35FDD7362F063A8706A2E7AFDB012974B1BB5
# backup from public schluessel (just for be safe)
gpg2 --armour -o dev@wrenix.eu.gpg --export B9C35FDD7362F063A8706A2E7AFDB012974B1BB5
# backup mit backup function (new for me, just for be safe)
gpg2 -o dev@wrenix.eu.private-bak.gpg --export-options backup --export-secret-keys B9C35FDD7362F063A8706A2E7AFDB012974B1BB5

3. Transfer des Schlüssel auf ein eToken

zunächst zurücksetzen

ykman fido reset
ykman oath reset
ykman openpgp reset
ykman otp delete 2
ykman otp delete 1
ykman piv reset

eToken / Smartcard einrichten

disable all not needed

ykman config usb -d OTP
ykman config usb -d OATH
ykman config usb -d PIV
ykman config usb -d HSMAUTH
# gpg2 --card-edit
Reader ...........: Yubico YubiKey FIDO CCID 00 00
Application ID ...: D1234567890123456789012345678901
Application type .: OpenPGP
Version ..........: x.y
Manufacturer .....: Yubico
Serial number ....: 12345678
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......: 
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> admin
Admin commands are allowed

gpg/card> passwd
gpg: OpenPGP card no. D1234567890123456789012345678901 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q
gpg/card> name
Cardholder's surname: WrenIX
Cardholder's given name: 

gpg/card> login
Login data (account name): wrenix

gpg/card> url
URL to retrieve public key: https://wrenix.eu/keys/dev.gpg

gpg/card> list

Reader ...........: Yubico YubiKey FIDO CCID 00 00
Application ID ...: D1234567890123456789012345678901
Application type .: OpenPGP
Version ..........: x.y
Manufacturer .....: Yubico
Serial number ....: 12345678
Name of cardholder: WrenIX  
Language prefs ...: [not set]
Salutation .......: 
URL of public key : https://wrenix.eu/keys/dev.gpg
Login data .......: wrenix
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> quit

Transfer der Schlüssels

Nun ab auf die Smartcard

# gpg2 --edit-key B9C35FDD7362F063A8706A2E7AFDB012974B1BB5
gpg (GnuPG) 2.4.0; Copyright (C) 2021 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.

Secret key is available.

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> key 2

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb* ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> keytocard 
Please select where to store the key:
   (3) Authentication key
Your selection? 3

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb* ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> key 2

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> key 1

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb* cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> keytocard 
Please select where to store the key:
   (2) Encryption key
Your selection? 2

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb* cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> key 1

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> key 0

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> keytocard 
Really move the primary key? (y/N) y
Please select where to store the key:
   (1) Signature key
   (3) Authentication key
Your selection? 1

sec  ed25519/0x7AFDB012974B1BB5
     created: 2023-05-17  expires: 2024-05-16  usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/0x4964120E6A1FB3D4
     created: 2023-05-17  expires: 2024-05-16  usage: E   
ssb  ed25519/0x133519C60482A816
     created: 2023-05-17  expires: 2024-05-16  usage: A   
[ultimate] (1). WrenIX <dev@wrenix.eu>

gpg> save

Verifiy

# gpg --card-status
Reader ...........: Yubico YubiKey FIDO CCID 00 00
Application ID ...: D1234567890123456789012345678901
Application type .: OpenPGP
Version ..........: x.y
Manufacturer .....: Yubico
Serial number ....: 12345678
Name of cardholder: WrenIX  
Language prefs ...: [not set]
Salutation .......: 
URL of public key : https://wrenix.eu/keys/dev.gpg
Login data .......: wrenix
Signature PIN ....: not forced
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: B9C3 5FDD 7362 F063 A870  6A2E 7AFD B012 974B 1BB5
      created ....: 2023-05-17 09:22:53
Encryption key....: 5BE1 61D4 F68C 442E AABC  B331 4964 120E 6A1F B3D4
      created ....: 2023-05-17 09:22:53
Authentication key: 1698 32F9 8797 2EFE AE29  4BD2 1335 19C6 0482 A816
      created ....: 2023-05-17 09:32:23
General key info..: pub  ed25519/0x7AFDB012974B1BB5 2023-05-17 WrenIX <dev@wrenix.eu>
sec>  ed25519/0x7AFDB012974B1BB5  created: 2023-05-17  expires: 2024-05-16
                                  card-no: 0006 12345678
ssb>  cv25519/0x4964120E6A1FB3D4  created: 2023-05-17  expires: 2024-05-16
                                  card-no: 0006 12345678
ssb>  ed25519/0x133519C60482A816  created: 2023-05-17  expires: 2024-05-16
                                  card-no: 0006 12345678

4 PGP-Key nutzen

Hierzu einfach die verschiedenen Fingerprints-Formate anzeigen lassen:

gpg2 -k --with-wkd-hash --with-keygrip --with-fingerprint

Bei mein Keys sind das demnach:

/home/wrenix/.gnupg/pubring.kbx
-------------------------------
pub   ed25519/0x7AFDB012974B1BB5 2023-05-17 [SC] [expires: 2024-05-16]
      Key fingerprint = B9C3 5FDD 7362 F063 A870  6A2E 7AFD B012 974B 1BB5
      Keygrip = E3C999FF61A1D44FB1D1E7CCAF59484A224D98DC
uid                   [ultimate] WrenIX <dev@wrenix.eu>
                      gudx35f8m3ns6jx87gkuda1nmtsb53nd@wrenix.eu
sub   cv25519/0x4964120E6A1FB3D4 2023-05-17 [E] [expires: 2024-05-16]
      Key fingerprint = 5BE1 61D4 F68C 442E AABC  B331 4964 120E 6A1F B3D4
      Keygrip = C674F36DB4CCF3299AA217F66EC40AAECC7774AA
sub   ed25519/0x133519C60482A816 2023-05-17 [A] [expires: 2024-05-16]
      Key fingerprint = 1698 32F9 8797 2EFE AE29  4BD2 1335 19C6 0482 A816
      Keygrip = 32FBA5CC5D0707227615543C81B3E72CBBAAD908

4.1 als SSH-Key nutzen

Dies gelingt uns in zwei Schritten:

1. ssh-agent in gpg aktivieren:

Wir können den GPG-Key Support in der Datei ~/.gnupg/gpg-agent.conf aktivieren, indem wir dort enable-ssh-support eintragen.

Ausserdem muss noch die Enviromentvariable SSH_AUTH_SOCK auf den SSH-Agent von GPG zeigen. Der befindet sich entweder in ~/.gnupg/S.gpg-agent.ssh oder in /run/user/$(uid)/gnupg/S.gpg-agent.ssh, dieser wird bei mir von NixOS mittels Home-Manager direkt gesetzt, indem ich die option services.gpg-agent.enableSshSupport setze.

2. GPG-Key in auswählen:

Den Authentifizierung Keygrip, in ~/.gnupg/sshcontrol eintragen.

An den Beispiel von mir, wäre es: 32FBA5CC5D0707227615543C81B3E72CBBAAD908

Kontrollieren

Ob am Ende alles funktioniert kann mit den Befehl ssh-add -L verifiziert werden. Dieser sollte daraufhin den Public-Key des SSH-Keys ausgeben:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGONGPQ79A9WZ7EwM6vMfBKBkgPD2dsjExFoo2UXyd79 (none)

4.2 in Webseite / Webkey-Deliever eintragen:

gpg2 --no-armour -o .well-known/openpgpkey/hu/gudx35f8m3ns6jx87gkuda1nmtsb53nd --export B9C35FDD7362F063A8706A2E7AFDB012974B1BB5