Using OpenPGP Keys For SSH Authentication

Consolidate your keys and prepare for using an OpenPGP smart card

 ·  4 minutes read

If you already use OpenPGP, there is no need for you to create an additional SSH key. You can just consolidate your identity and use the same key for SSH authentication. The main benefits that come to mind are:

  1. Preparing yourself for your eventual migration to using an OpenPGP smart card (hereby: SmartCard) like the YubiKey NEO.
  2. Having one less key to worry about.

The rest of this post assumes:

  1. You use GnuPG version 2.1 or later (run gpg --version to verify).
  2. You already have an OpenPGP key (plenty of tutorials online).
  3. You already use gpg-agent as your SSH agent (plenty of tutorials online).

Create an Authentication subkey

We first need to open the relevant key for editing in expert mode:

$ gpg --expert --edit-key 7C477933
Secret key is available.

pub  rsa4096/7C477933
     created: 2011-12-20  expires: never       usage: SC
     trust: ultimate      validity: ultimate
sub  rsa2048/03879636
     created: 2015-09-15  expires: never       usage: S
sub  rsa2048/DCAAEEF7
     created: 2015-09-15  expires: never       usage: E
[ultimate] (1). Tom <tom@example.org>

Now we are going to add a new authentication key:

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?

Select (8) RSA (set your own capabilities).

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?

Select (S), (E) and (A) until the current allowed actions contains only Authenticate, and then select (Q) to finish.

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)

Select 2048, because as of now, this is the largest key size supported by the YubiKey and many other SmartCards, and is safe enough anyway.

Continue with setting expiration and following instructions. After the key has been generated run:

gpg> save

You will now see the same output as when we first ran gpg --expert --edit-key 7C477933 with the newly added key included:

sub  rsa2048/D184E14E
     created: 2015-09-15  expires: never       usage: A

Where A indicates this subkey is used for authentication.

Adding the key to the agent

There are two possible alternatives for using the newly generated key. Using a SmartCard or not.

Without a SmartCard

First we need to find our key's keygrip, this can be done by running gpg -K --with-keygrip and locating our key: So for the new key in our example, this should look something like:

sub   rsa2048/D184E14E 2015-09-15
      Keygrip = 58E0D19FEDB89C6659903C9CC1ADCC7801022844

After that open ~/.gnupg/sshcontrol with your favourite editor, and append the keygrip found, as follows:

07D52A07249804D0D91C43400B3DA881F048512D

With a SmartCard

Important: This section explains how to move your private key to the SmartCard. This is not reversible, so please make sure you have a valid backup of the key before continuing.

This is very easy. First, let's open the key for editing:

$ gpg --edit-key 7C477933
Secret key is available.

pub  rsa4096/7C477933
     created: 2011-12-20  expires: never       usage: SC
     trust: ultimate      validity: ultimate
sub  rsa2048/03879636
     created: 2015-09-15  expires: never       usage: S
sub  rsa2048/DCAAEEF7
     created: 2015-09-15  expires: never       usage: E
sub  rsa2048/D184E14E
     created: 2015-09-15  expires: never       usage: A
[ultimate] (1). Tom <tom@example.org>

Run toggle to switch to secret key mode:

gpg> toggle

Choose the authentication key:

gpg> key 3

pub  rsa4096/7C477933
     created: 2011-12-20  expires: never       usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa2048/03879636
     created: 2015-09-15  expires: never       usage: S
ssb  rsa2048/DCAAEEF7
     created: 2015-09-15  expires: never       usage: E
ssb* rsa2048/D184E14E
     created: 2015-09-15  expires: never       usage: A
[ultimate] (1). Tom <tom@example.org>

Move it to the card:

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

Select 3, because the key we chose is an authentication key, as denoted by the A in the usage field.

If you wish to also move the encryption key and signature key to the card, please repeat the previous stages for those too.

To finish, enter quit:

gpg> quit
Save changes? (y/N) y

This is it, you now have your keys on your SmartCard, and they are ready to be used.

Using the key

Now we should have everything set up correctly. The only thing left to do is finding our public-key. Assuming everything works as expected, this is very easy:

$ ssh-add -L
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCg7H7iQVOXeHCWefQv1UH97Ow78KK7qZoRwKBLLOh1gJEDnFGhIbTnxdpMJUzj/4TE+V/D06iFO22+Ohn0MY3GP91V9/XXXjvEDCYpRR3ftzhr1+AibDAJK3XFKcq6TQeag1Ib+4zSwsDxUs4Sei9YF40hO8pqfmqhRaW3YUJBdj8vVOCatm6IaLUfSIjzLHY9WggA3aeR48UMSl7DT4EdeqHjtZHxXKYdOw3ymt/zyGfwuc9MNlzcmixINZSmW4jZTLXlTxhbCFlpp77ksuV605xUgl6+kgYNnni2t4VztwP9AH8yEjcdopasm1sObHcyEpq1BVxJtlShVDNl8ufb cardno:000603638479

This will list all of the keys loaded in your agent. If you use a SmartCard, look for the one with the comment that starts with cardno:, or if you don't use a SmartCard, for the one with the comment (none). This is your public-key and you can use it like you would normally.

Conclusion

As you can see, this is useful, very easy to do and is required for using a SmartCard, a highly recommended practice.

Please let me know if you have spotted any mistakes or have any suggestions.

Please let me know if you spotted any mistakes or have any suggestions, and follow me on Twitter or RSS for updates.

security pgp ssh