GPG a Yubikey

Nastavení GPG klíčů pro certitikování, šifrování a autorizaci. Master klíč v offline úložišti a ostatní na Yubikey klíči.

Warning

U všech příkazů platí: dvakrát měř, jednou řež!

Note

Zkoušeno na systému MX Linux

Cíl

GPG klíče pro podpis git commitů, použití GPG klíčů na přihlášení přes SSH na servery.

Postup

1. Základní příprava

Nejprve si připravím čistý adresář ~/.gnupg

$ cd ~
$ mv .gnupg .gnupg.old
$ mkdir .gnupg
$ chmod 700 ~/.gnupg

Ze svých .dotfiles nainstalovat nastavení pro gpg, gpg-agenta, dirmngr...

$ cd ~/.dotfiles
$ ./setup.sh
$ cd ~/.gnupg
$ ls
dirmngr.conf  gpg-agent.conf  gpg.conf  scdaemon.conf  scd-event  sks-keyservers.netCA.pem
$ gpg --list-keys
gpg: keybox '/home/michal/.gnupg/pubring.kbx' created
gpg: /home/michal/.gnupg/trustdb.gpg: trustdb created

Nyní mám připravený adresář pro GPG a můžu se do toho pustit.

Note

Vše lze také provést v libovolném adresáři tak, že exportuji proměnnou GNUPGHOME` nebo použiji možnost --homedir při spouštění příkazu.

$ export GNUPGHOME=~/foobar
$ gpg --list-keys
gpg: keyblock resource '/home/michal/foobar/pubring.kbx': Adresář nebo soubor neexistuje
gpg: Fatal: /home/michal/foobar: directory does not exist!

GPG bude nyní hledat domovský adresář na zadané lokalitě!

2. Vygenerování master klíče

Vynegerujeme si hlavní tzv. master klíč (typ RSA, dlouhý 4096 bitů) jen pro certifikaci. Ostatní klíče budou podklíče tohoto hlavního klíče. Platnost dávám neomezenou.

$ gpg --full-gen-key --expert
gpg (GnuPG) 2.1.18; Copyright (C) 2017 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)
   (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)
Your selection? 8

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

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

Your selection? s

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify Encrypt

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

Your selection? e

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Certify

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

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 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) 0
Key does not expire at all
Is this correct? (y/N) y

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

Real name: Michal Moravec
Email address: mishal@mishal.cz
Comment:
You selected this USER-ID:
    "Michal Moravec <mishal@mishal.cz>"

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.
gpg: key 0xC0C70FC4FD79208A marked as ultimately trusted
gpg: directory '/home/michal/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/michal/.gnupg/openpgp-revocs.d/D47ED2989AB86FA1ED992760C0C70FC4FD79208A.rev'
public and secret key created and signed.

pub   rsa4096/0xC0C70FC4FD79208A 2018-09-27 [C]
      Key fingerprint = D47E D298 9AB8 6FA1 ED99  2760 C0C7 0FC4 FD79 208A
uid                              Michal Moravec <mishal@mishal.cz>

Ověříme si, zda je klíč vygenerován.

$ gpg --list-keys
/home/michal/.gnupg/pubring.kbx
-------------------------------
pub   rsa4096/0xC0C70FC4FD79208A 2018-09-27 [C]
      Key fingerprint = D47E D298 9AB8 6FA1 ED99  2760 C0C7 0FC4 FD79 208A
uid                   [ultimate] Michal Moravec <mishal@mishal.cz>

Vygenerujeme si (raději) další revokační certifikát pro případ, že by bylo nutné tento klíč revokovat.

$ gpg --generate-revocation 0xC0C70FC4FD79208A > 0xC0C70FC4FD79208A_revocation.asc

sec  rsa4096/0xC0C70FC4FD79208A 2018-09-27 Michal Moravec <mishal@mishal.cz>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 1
Enter an optional description; end it with an empty line:
>
Reason for revocation: Key has been compromised
(No description given)
Is this okay? (y/N) y
ASCII armored output forced.

3. Vygenerování podklíče pro šifrování

Podklíč vytvořime tak, že budeme editovat master klíč. Pomocí příkazu help si můžeme zobrazit nápovědu. Příkazem addkey a save provedeme přidání klíče.

$ gpg --edit-key 0xC0C70FC4FD79208A
gpg (GnuPG) 2.1.18; Copyright (C) 2017 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  rsa4096/0xC0C70FC4FD79208A
     created: 2018-09-27  expires: never       usage: C
     trust: ultimate      validity: ultimate
[ultimate] (1). Michal Moravec <mishal@mishal.cz>

gpg> help
quit        quit this menu
save        save and quit
help        show this help
fpr         show key fingerprint
grip        show the keygrip
list        list key and user IDs
uid         select user ID N
key         select subkey N
check       check signatures
sign        sign selected user IDs [* see below for related commands]
lsign       sign selected user IDs locally
tsign       sign selected user IDs with a trust signature
nrsign      sign selected user IDs with a non-revocable signature
adduid      add a user ID
addphoto    add a photo ID
deluid      delete selected user IDs
addkey      add a subkey
addcardkey  add a key to a smartcard
keytocard   move a key to a smartcard
bkuptocard  move a backup key to a smartcard
delkey      delete selected subkeys
addrevoker  add a revocation key
delsig      delete signatures from the selected user IDs
expire      change the expiration date for the key or selected subkeys
primary     flag the selected user ID as primary
pref        list preferences (expert)
showpref    list preferences (verbose)
setpref     set preference list for the selected user IDs
keyserver   set the preferred keyserver URL for the selected user IDs
notation    set a notation for the selected user IDs
passwd      change the passphrase
trust       change the ownertrust
revsig      revoke signatures on the selected user IDs
revuid      revoke selected user IDs
revkey      revoke key or selected subkeys
enable      enable key
disable     disable key
showphoto   show selected photo IDs
clean       compact unusable user IDs and remove unusable signatures from key
minimize    compact unusable user IDs and remove all signatures from key

* The 'sign' command may be prefixed with an 'l' for local signatures (lsign),
  a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures
  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).

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)
Your selection? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 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) 0
Key does not expire at all
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  rsa4096/0xC0C70FC4FD79208A
     created: 2018-09-27  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xA4DAF18F73F0F6E4
     created: 2018-09-27  expires: never       usage: E
[ultimate] (1). Michal Moravec <mishal@mishal.cz>

gpg> save

4. Vygenerování podklíče pro podepisování

Postupujeme jako v předchozíme kroku, jen vybereme sign only.

$ gpg --edit-key 0xC0C70FC4FD79208A
gpg (GnuPG) 2.1.18; Copyright (C) 2017 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  rsa4096/0xC0C70FC4FD79208A
     created: 2018-09-27  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xA4DAF18F73F0F6E4
     created: 2018-09-27  expires: never       usage: E
[ultimate] (1). Michal Moravec <mishal@mishal.cz>

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)
Your selection? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 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) 0
Key does not expire at all
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  rsa4096/0xC0C70FC4FD79208A
     created: 2018-09-27  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xA4DAF18F73F0F6E4
     created: 2018-09-27  expires: never       usage: E
ssb  rsa4096/0x798865C927B64D7D
     created: 2018-09-27  expires: never       usage: S
[ultimate] (1). Michal Moravec <mishal@mishal.cz>

gpg> save
$ gpg --list-keys
/home/michal/.gnupg/pubring.kbx
-------------------------------
pub   rsa4096/0xC0C70FC4FD79208A 2018-09-27 [C]
      Key fingerprint = D47E D298 9AB8 6FA1 ED99  2760 C0C7 0FC4 FD79 208A
uid                   [ultimate] Michal Moravec <mishal@mishal.cz>
sub   rsa4096/0xA4DAF18F73F0F6E4 2018-09-27 [E]
sub   rsa4096/0x798865C927B64D7D 2018-09-27 [S]

5. Vygenerování podklíče pro autorizaci

Postupujeme podobně jako v předchozíme kroku, ale musíme příkaz spustit v expertním režimu pomocí --exprert.

$ gpg --expert --edit-key 0xC0C70FC4FD79208A
gpg (GnuPG) 2.1.18; Copyright (C) 2017 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  rsa4096/0xC0C70FC4FD79208A
     created: 2018-09-27  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xA4DAF18F73F0F6E4
     created: 2018-09-27  expires: never       usage: E
ssb  rsa4096/0x798865C927B64D7D
     created: 2018-09-27  expires: never       usage: S
[ultimate] (1). Michal Moravec <mishal@mishal.cz>

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
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt

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

Your selection? a

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt Authenticate

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

Your selection? s

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt Authenticate

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

Your selection? e

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate

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

Your selection? q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 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) 0
Key does not expire at all
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  rsa4096/0xC0C70FC4FD79208A
     created: 2018-09-27  expires: never       usage: C
     trust: ultimate      validity: ultimate
ssb  rsa4096/0xA4DAF18F73F0F6E4
     created: 2018-09-27  expires: never       usage: E
ssb  rsa4096/0x798865C927B64D7D
     created: 2018-09-27  expires: never       usage: S
ssb  rsa4096/0x517423AA911CD850
     created: 2018-09-27  expires: never       usage: A
[ultimate] (1). Michal Moravec <mishal@mishal.cz>

gpg> save

6. Záloha

Nyní máme potřebné klíče připravené a nakopírujeme si vše na bezpečné místo - USB, která bude zakopaná na tajném místě na pozemku. Vytvoříme si i vytištěnou verzi privátního klíče.

$ sudo aptitude install paperkey
$ gpg --export-secret-key 0xC0C70FC4FD79208A | paperkey > 0xC0C70FC4FD79208A.txt
$ gpg --export-secret-key 0xC0C70FC4FD79208A > C0C70FC4FD79208A.asc

Textový soubor si vytisknu.

Celý adresář .gnupg si nakopíruji na bezpečné umístění.

7. Nastavení uid

Editací klíče si můžu přidat ke klíči další identity (přikazy uid, primary...).

8. Smazání privátního klíče

Privátní klíč smažu jednoduše tak, že smažu soubor, který klíč obsahuje (.gnupg/private-keys-v1.d/<KEYGRIP>.key). Jeho název odpovídá hodnotě keygrip.

/home/michal/.gnupg/pubring.kbx
-------------------------------
sec   rsa4096/0xC0C70FC4FD79208A 2018-09-27 [C]
      Key fingerprint = D47E D298 9AB8 6FA1 ED99  2760 C0C7 0FC4 FD79 208A
      Keygrip = 4A44DB1C492A6A14A588DD99C15A298EB434DF46
uid                   [ultimate] Michal Moravec <mishal@mishal.cz>
uid                   [ultimate] Michal Moravec <michal.moravec@bc.cas.cz>
ssb   rsa4096/0xA4DAF18F73F0F6E4 2018-09-27 [E]
      Keygrip = 719C0E9B9106DCFF5E8E005E49314372E02DCAE8
ssb   rsa4096/0x798865C927B64D7D 2018-09-27 [S]
      Keygrip = E1DB80F05235A6669C813988EF2D88979FEA63D7
ssb   rsa4096/0x517423AA911CD850 2018-09-27 [A]
      Keygrip = 16856B9ACF707725163488C1E95BF05A0DC8A367

Smazání přes API lze provést i příkazem:

gpg-connect-agent "DELETE_KEY 4A44DB1C492A6A14A588DD99C15A298EB434DF46" /bye

9. Přesun klíčů na Yubikey

Připravené klíče nyní přesuneme na Yubikey. Budeme editovat hlavní klíč, pomocí key <cislo> označíme jaký klíč chceme přesunout. Přesuneme postupně klíče E, S, a A.

gpg --edit-key 0xC0C70FC4FD79208A

10. SSH autorizace

Klíč pro SSH autrizaci si zobrazíme pomocí:

ssh-add -L

Tento klíč nakopírujeme na potřebné stroje do souboru ~/.ssh/authorized_keys.