Skip to main content

Generating a GPG key with smartcard and SSH Authentication

·5 mins

This document will get you step by step through the generation of a GPG smartcard key, with the correct subkeys for use on a smartcard like the OpenPGP smartcard or a Yubikey. This will also allow you to use your GPG Authentication subkey for SSH support.

Generating a key #

Generating the masterkey #

With a smartcard key, you split your key into a master key (certify key) and individual subkeys (signing, encrypting, authentication). Often this is done on a airgapped machine. First off, you generate the key using expert mode:

gpg --full-generate-key --expert

Choose option “RSA (set your own capabilities)”, which is currently number 8 and toggle the sign (S) and encrypt (E) by selecting the option and confirming with enter. The only option on this key should be Certify! Then press Q followed by enter to finish.

For keysize, choose 4096 and confirm with enter. For the expire date, choose 10y and confirm with enter. and yes.

Fill in your full name and email, leave the comment blank, confirm your choice and enter in your passphrase.

You should now have a masterkey, it should show the fingerprint on the screen. (example: 34B35DD172E366BF6867AB069FB800372F2546D8)

Creating your subkeys #

Now we are going to add the capability to sign or decrypt messages and use the key for ssh authentication.

gpg --expert --edit-key <YOUR FINGERPRINT>

In this interface, you are going to generate some subkeys:

Signing key #

addkey

Choose option “RSA (set your own capabilities)”, which is currently number 8. Toggle E (encryption) so the “Current allowed actions” only lists Sign and confirm with Q. Choose the keysize 4096. Choose the key expire date 3y. Confirm twice, then enter your passphrase.

Encryption key #

addkey

Choose option “RSA (set your own capabilities)”, which is currently number 8. Toggle S (Signing) so the “Current allowed actions” only lists Encrypt and confirm with Q. Choose the keysize 4096. Choose the key expire date 3y. Confirm twice, then enter your passphrase.

Authentication key #

addkey

Choose option “RSA (set your own capabilities)”, which is currently number 8. Toggle S (Signing), E (Encryption) and A (Authentication) so the “Current allowed actions” only lists Authenticate and confirm with Q. Choose the keysize 4096. Choose the key expire date 3y. Confirm twice, then enter your passphrase.

Trusting the keys and finishing up #

Type in the command:

trust

Choose 5, confirm. Type in:

save

And check if you have multiple subkeys like such:

$ gpg --list-key 015E51CA677A864C61F13D13149B9E17245535D8

pub   rsa4096 2020-03-26 [C] [expires: 2030-03-24]
      015E51CA677A864C61F13D13149B9E17245535D8
uid           [ultimate] Test testtt <[email protected]>
sub   rsa4096 2020-03-26 [S] [expires: 2023-03-26]
sub   rsa4096 2020-03-26 [E] [expires: 2023-03-26]
sub   rsa4096 2020-03-26 [A] [expires: 2023-03-26]

It should show 3 subkeys with a letter S, E and A, as well as the master key with the letter C!

Backups #

One of the most important things. Backup your key now since you have everything in one place!

gpg --output revoke.asc --gen-revoke <YOUR FINGERPRINT>
gpg --armor --output privkey.sec --export-secret-key <YOUR FINGERPRINT>
gpg --armor --output subkeys.sec --export-secret-subkeys <YOUR FINGERPRINT>
gpg --armor --output pubkey.asc --export <YOUR FINGERPRINT>

Save these files somewhere safe. You need access to them if you lose your token or need to edit the expiration date. Share the pubkey.asc file with whoever you want to send you encrypted messages.

Initialising the smartcard #

Insert your smartcard, and execute the following command:

gpg --card-edit

Do the following, between parenthesis are comments:

admin
passwd
(change admin pin, currently option 3, default is 12345678)
3
(change this to a random, new 8 numeric code)
(set the reset code, option 4, use your admin pin)
4
(change this to a random, new 8 numeric code)
1 
(change this to a random, new 6 numeric code. Default is 123456 This is the one you will use during signing or encryption)
q
name
(enter your (nick)name)
url
(enter the https location of your public key file)
quit

Pushing the subkeys to the smartcard #

Execute the following:

gpg --expert --edit-key <YOUR FINGERPRINT>

Then here, do the following:

toggle
key 1
keytocard

Now take a look at the selected key after “key 1”, it should be the one with “usage: S” Select the storage slot “Signature key” (1) Enter your passphrase for your gpg masterkey. Enter the ADMIN PINCODE you changed above.

Then run:

key 1


key 2
keytocard

This should be your encryption key with “usage: E” Select the storage slot “Encryption key” (2) Enter your passphrase for your gpg masterkey. Enter the ADMIN PINCODE you changed above.

Then run:

key 2
key 3
keytocard

This should be your authentication key with “usage: A” Select the storage slot “Authentication key” (3) Enter your passphrase for your gpg masterkey. Enter the ADMIN PINCODE you changed above.

Finish with:

save

Testing the key #

Test your key with the following, it should prompt for your pincode instead of passphrase and show a signed message:

echo "test" | gpg -a -u <your fingerprint> --sign

Using on another computer #

This is very easy to do, insert your token and run. This will import your public key and connect it to the smartcard. This only works if your public key is already uploaded to the location of the URL field in your card.

gpg --card-edit
fetch
quit

Enabling SSH support #

Add enable-ssh-support and write-env-file to ~/.gnupg/gpg-agent.conf

Restart GPG agent or reboot.

Check echo $SSH_AUTH_SOCK - it should be pointing to gpg-agent’s socket instead of ssh-agent.

Check your authentication key fingerprint’s last 16 characters by running:

$ gpg --fingerprint --fingerprint 015E51CA677A864C61F13D13149B9E17245535D8

pub   rsa4096 2020-03-26 [C] [expires: 2030-03-24]
      015E 51CA 677A 864C 61F1  3D13 149B 9E17 2455 35D8
uid           [ultimate] Test testtt <[email protected]>
sub   rsa4096 2020-03-26 [S] [expires: 2023-03-26]
      0612 76E3 8F5B 2F4D 095F  95A0 286E 51F1 6D91 53EE
sub   rsa4096 2020-03-26 [E] [expires: 2023-03-26]
      D7C6 3D9E 78BE 0932 F844  42DA 60D9 8F16 D50B B177
sub   rsa4096 2020-03-26 [A] [expires: 2023-03-26]
      CD1F B5B8 78F2 A1DE B036  6D90 3BF1 9BEC 700E 4870

Look at the subkey here with “[A]”, copy the 4 groups at the end, in this case: 3BF1 9BEC 700E 4870

Remove the spaces: 3BF19BEC700E4870 and run (keep the exclamation mark in mind!):

gpg -o gpg_ssh.pub --export-ssh-key 3BF19BEC700E4870!

You now have your ssh key in gpg_ssh.pub which you can use on servers like you normally would with SSH keys.