Skip to content

Instantly share code, notes, and snippets.

@mc2pw
Last active October 22, 2023 02:32
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mc2pw/88999df65f32cad4bb2d to your computer and use it in GitHub Desktop.
Save mc2pw/88999df65f32cad4bb2d to your computer and use it in GitHub Desktop.
Setting up Keys on Tails

In a previous post I introduced the Tails operating system, and listed some steps for getting started. I lay out here some steps for configuring SSH and getting started with GPG.

SSH

Go to the .ssh directory and create a private key (identity file) and public key pair.

$ cd ~/.ssh
$ ssh-keygen -t rsa -b 4096 -C "<email>"

To make it easier to use multiple public keys, log into in multiple ssh servers, create a file named config, with content similar to this.

IdentitiesOnly yes

Host github.com gh
    HostName github.com
    User git
    IdentityFile ~/.ssh/github

Setting IdentitiesOnly to yes makes the ssh command use the authentication identity files specified for the server in the config files.

The fingerprint for GitHub appears here. To list the known ssh fingerprints run ssh-keygen -l -f ~/.ssh/known_hosts.

GPG

As can be seen in the gpg config file ~/.gnupg/gpg.conf, Tails already implements best practices from riseup.net.

We start Tails in a trusted machine without a root password and without persistence. We assume that the persistent drive can also be trusted, since this will be mounted to store the keys when they are ready.

Create a key 4096 bit RSA key with the sha512 hashing algorithm (gpg.conf will take care of the hashing algorithm) as recommended by the aforementioned best practices. You will be prompted for a comment, it is best left empty.

amnesia@amnesia:~$ gpg --gen-key
gpg (GnuPG) 1.4.12; Copyright (C) 2012 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? 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
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 2y
Key expires at Tue 26 Sep 2017 03:06:10 PM UTC
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 Email Address in this form:
    "Heinrich Heine (Der Dichter) "

Real name: Luis Gabriel Peña García
Email address: luispena@mail.ru
Comment: 
You are using the `utf-8' character set.
You selected this USER-ID:
    "Luis Gabriel Peña García "

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

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 0xE4A8641965655555 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:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2017-09-26
pub   4096R/0xE4A8641965655555 2015-09-27 [expires: 2017-09-26]
      Key fingerprint = 7B27 7F2C 8CE9 0583 E33B  2B2E E4A8 6419 6565 5555
uid                 [ultimate] Luis Gabriel Peña García 

Note that this key cannot be used for encryption.  You may want to use
the command "--edit-key" to generate a subkey for this purpose.

So far we have the bare minimum for using GPG, e.g. we can use this key for signing our git commits and tags. We show some additional steps needed for encrypting messages and using the key more securely.

Add subkeys for encryption and signing. Remember Plausible deniability and the lack of forward security and make judicious use of your signing and encryption keys.

amnesia@amnesia:~$ gpg --edit-key 0xE4A8641965655555
gpg (GnuPG) 1.4.12; Copyright (C) 2012 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.

pub  4096R/0xE4A8641965655555  created: 2015-09-27  expires: 2017-09-26  usage: SC  
                               trust: ultimate      validity: ultimate
[ultimate] (1). Luis Gabriel Peña García 

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Luis Gabriel Peña García "
4096-bit RSA key, ID 0xE4A8641965655555, created 2015-09-27

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
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 2y
Key expires at Tue 26 Sep 2017 03:12:14 PM UTC
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.
.....................+++++
...............+++++

pub  4096R/0xE4A8641965655555  created: 2015-09-27  expires: 2017-09-26  usage: SC  
                               trust: ultimate      validity: ultimate
sub  4096R/0xE0901B84A589E428  created: 2015-09-27  expires: 2017-09-26  usage: E   
[ultimate] (1). Luis Gabriel Peña García 

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Luis Gabriel Peña García "
4096-bit RSA key, ID 0xE4A8641965655555, created 2015-09-27

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
        = key expires in n days
      w = key expires in n weeks
      m = key expires in n months
      y = key expires in n years
Key is valid for? (0) 2y
Key expires at Tue 26 Sep 2017 03:16:37 PM UTC
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.
.........................+++++
....+++++

pub  4096R/0xE4A8641965655555  created: 2015-09-27  expires: 2017-09-26  usage: SC  
                               trust: ultimate      validity: ultimate
sub  4096R/0xE0901B84A589E428  created: 2015-09-27  expires: 2017-09-26  usage: E   
sub  4096R/0x9B9EF0367B6D7000  created: 2015-09-27  expires: 2017-09-26  usage: S   
[ultimate] (1). Luis Gabriel Peña García 

gpg> save

We now have the master key along with two subkeys. The master key should be kept entirely offline. More details on this can be found in the answers to this this stackexchange question. Here Thomas Pornin points out that the primary key should only be used "to emit sub-keys, i.e. once in a decade at most." However, Simon Josefsson shows in this post the steps for signing keys (including someone else's keys) using the master key.

Create an encrypted file with the contents of ~/.gnupg and store it in the persistent drive. You may need to use a different directory (one with appropriate permission settings) for now.

amnesia@amnesia:~$ gpg-zip -c -o /media/TailsData/Keys/gnupg-master.gpg .gnupg

This is where the master key will remain. Keeping the master key entirely offline means in particular that the password of gnupg-master.gpg should not be input while persistence is enabled.

Generate a revocation certificate and store it in a safe place. If possible, print it.

amnesia@amnesia:~$ gpg --output revoke.asc --gen-revoke 0xE4A8641965655555

sec  4096R/0xE4A8641965655555 2015-09-27 Luis Gabriel Peña García 

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

You need a passphrase to unlock the secret key for
user: "Luis Gabriel Peña García "
4096-bit RSA key, ID 0xE4A8641965655555, created 2015-09-27

ASCII armored output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!

Remove the master key, so that we can make ~/.gnupg persistent. The output of gpg -K will show a # after sec when the master key is no longer available.

amnesia@amnesia:~$ gpg -K
/home/amnesia/.gnupg/secring.gpg
--------------------------------
sec   4096R/0xE4A8641965655555 2015-09-27 [expires: 2017-09-26]
      Key fingerprint = 7B27 7F2C 8CE9 0583 E33B  2B2E E4A8 6419 6565 5555
uid                            Luis Gabriel Peña García 
ssb   4096R/0xE0901B84A589E428 2015-09-27
ssb   4096R/0x9B9EF0367B6D7000 2015-09-27

amnesia@amnesia:~$ gpg --export-secret-subkeys 0xE0901B84A589E428 0x9B9EF0367B6D7000 > subkeys.txt
amnesia@amnesia:~$ gpg --export 0xE4A8641965655555 > pubkeys.txt
amnesia@amnesia:~$ gpg --delete-secret-key 0xE4A8641965655555
gpg (GnuPG) 1.4.12; Copyright (C) 2012 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.


sec  4096R/0xE4A8641965655555 2015-09-27 Luis Gabriel Peña García 

Delete this key from the keyring? (y/N) y
This is a secret key! - really delete? (y/N) y
amnesia@amnesia:~$ gpg --import subkeys.txt pubkeys.txt 
gpg: key 0xE4A8641965655555: secret key imported
gpg: key 0xE4A8641965655555: "Luis Gabriel Peña García " not changed
gpg: key 0xE4A8641965655555: "Luis Gabriel Peña García " not changed
gpg: Total number processed: 2
gpg:              unchanged: 2
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
amnesia@amnesia:~$ gpg -K
/home/amnesia/.gnupg/secring.gpg
--------------------------------
sec#  4096R/0xE4A8641965655555 2015-09-27 [expires: 2017-09-26]
      Key fingerprint = 7B27 7F2C 8CE9 0583 E33B  2B2E E4A8 6419 6565 5555
uid                            Luis Gabriel Peña García 
ssb   4096R/0xE0901B84A589E428 2015-09-27
ssb   4096R/0x9B9EF0367B6D7000 2015-09-27

The keys are now ready, so we make them persistent by doing one of the following.

  • Replacing the contents of ~/.gnupg for those of /media/TailsData/gnupg
  • Copying the files subkeys.txt and pubkeys.txt into the persistent drive, and importing them into gpg when persistence is enabled
  • (Do this only if /media/TailsData/gnupg has previously been copied from ~/.gnupg, which is configured appropriately) Setting the environment variable GNUPGHOME to /media/TailsData/gnupg, and importing subkeys.txt and pubkeys.txt into gpg.

The next time you start Tails with persistence, you can share your key with the keyservers.

gpg --send-key '<fingerprint>'

Edit the Key

Summary of GPG Commands

Create the Key

  1. Generate the master key
amnesia@amnesia:~$ gpg --gen-key
  1. Add a subkey
amnesia@amnesia:~$ gpg --edit-key
gpg> addkey
gpg> save
  1. Backup $GNUGPHOME
amnesia@amnesia:~$ gpg-zip -c -o /media/TailsData/Keys/gnupg-master.gpg $GNUPGHOME$
  1. Generate revokation ceritficate
amnesia@amnesia:~$ gpg --output revoke.asc --gen-revoke 0xE4A8641965655555
  1. Export secret subkeys and public keys, and delete the entire key (master key and subkeys, public and private)
amnesia@amnesia:~$ gpg --export-secret-subkeys 0xE0901B84A589E428 0x9B9EF0367B6D7000 > subkeys.txt
amnesia@amnesia:~$ gpg --export 0xE4A8641965655555 > pubkeys.txt
amnesia@amnesia:~$ gpg --delete-secret-key 0xE4A8641965655555
  1. Import the key (public master key, public and private subkeys)
amnesia@amnesia:~$ gpg --import subkeys.txt pubkeys.txt
  1. List all secret keys (the keys are now ready to use, make them persistent if you haven't)
amnesia@amnesia:~$ gpg -K # -K is the same as --list-secret-keys

Share Keys

  1. Share your public keys with the world
amnesia@amnesia:~$ gpg --send-key ''
  1. Receive public key from key servers, and (in order versions of gpg) check that you actually received a key with that fingerprint
amnesia@amnesia:~$ gpg --recv-key ''
amnesia@amnesia:~$ gpg --fingerprint ''
  1. Refresh keys

  2. Refresh

  3. Import public keys

  4. Use private subkeys for encrypting, signing

amnesia@amnesia:~$ gpg -e -u "Sender User Name" -r "Receiver User Name" somefile
amnesia@amnesia:~$ gpg --send-key ''
  1. Use public keys for decrypting and verifying
amnesia@amnesia:~$ gpg --send-key ''
amnesia@amnesia:~$ gpg --send-key ''

Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment