DEV Community

Cover image for Step by step guide on how to set up Yubikey with GPG subkeys
Igor Cekelis
Igor Cekelis

Posted on • Updated on • Originally published at barrage.net

Step by step guide on how to set up Yubikey with GPG subkeys

Everything around us is moving to digital. Our society is becoming more dependent upon online platforms, and it grows increasingly important that we embrace stronger online security measures.

Basic two-factor authentication using 6 digits and a mobile app is not enough to keep personal and professional accounts and services secured.

This method can be abused in a number of ways, like phishing attacks, third party login, and brute force.

Because of this, it’s essential for professionals to add another layer of protection, incorporating hardware devices like smart cards, and YubiKey is a popular choice for it. It allows your private key to be stored and accessed only when you need it to decrypt your data.

Up next is a simple and straightforward guide on generating GPG keys via your machine and transferring them to the security dongle YubiKey 4.

What is GPG?

GPG, or GNU Privacy Guard, is a public key cryptography implementation. This allows for the secure transmission of information between parties and can be used to verify that the origin of a message is genuine.

What is YubiKey?

The YubiKey is a hardware authentication device manufactured by Yubico that supports one-time passwords, public-key cryptography and authentication, and the Universal 2nd Factor and FIDO2 protocols developed by the FIDO Alliance.

Now that we covered all the basics let’s get to work.

Prerequisite

Before starting this guide, you need to download the GPG Suite.

If you work on macOS, click here to download the software installer and install it. If you work on Linux, you already have it preinstalled.

Also, you have to have a YubiKey!

Step 1 - generate Certify key

Start key generation by running the following command:

gpg --full-generate-key --expert
Enter fullscreen mode Exit fullscreen mode

Certify key generation - step 1

-> gpg --full-generate-key --expert
gpg (GnuPG) 2.2.19; Copyright (C) 2019 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)
  (13) Existing key
  (14) Existing key from card
Your selection? 8
Enter fullscreen mode Exit fullscreen mode

Select 8 ( RSA - set your own capabilities) and press enter.

On this prompt, it is necessary to toggle off sign capability (S) and encrypt capability (E) by entering capital letter associated with it and pressing enter.

When "Current allowed actions" has only "Certify", insert Q(finished) and press enter.

Certify key generation - step 2

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
Enter fullscreen mode Exit fullscreen mode

In the following step when prompted for key size put 4096 and press enter, after that it will prompt you to input key expiration time. For this step only set it as 0 (key does not expire), press enter, and then insert y to confirm and press enter again.

RSA keys may be between 1024 and 4096 bits long. 
What keysize do you want? (3072) 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) 
Key does not expire at all 
Is this correct? (y/N) y
Enter fullscreen mode Exit fullscreen mode

Afterward, it will request your name and email address to construct a user ID to identify the key.

The comment is optional. When satisfied enter O (Okay) and press enter.

Key identification

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:
     "John Doe (Some Comment) <john.doe@email.com>" 
Real name: Real Name 
E-mail address: real.name@barrage.net 
Comment: 
You selected this USER-ID:
     "Real Name <real.name@barrage.net>" 
Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? o
Enter fullscreen mode Exit fullscreen mode

Important: Popup window requesting to set passphrase will show. (it is recommended to save passphrase in LastPass or another secure password manager)

After you have set the passphrase your key has been created and you will get a message similar to one in the snipper below.

Key generation - random bytes

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, utilise the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy.
gpg: key 9CD3AF89EB04F8FF marked as ultimately trusted
gpg: directory '/home/realname/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/realname/.gnupg/openpgp-revocs.d/DAF272D92DAE18C1790A1E8A7C258D4980E4DCB5.rev'
public and secret key created and signed.

pub   rsa4096 2020-06-17 [C]
      DAF272D92DAE18C1790A1E8A7C258D4980E4DCB5
uid                      Real Name <real.name@barrage.net>

Enter fullscreen mode Exit fullscreen mode

You have now generated your certification key.

Step 2 - create RSA sign only key

After we have created the key for the certificate we need to add the rest of them.

gpg --edit-key --expert <your_email_address>
Enter fullscreen mode Exit fullscreen mode

(the address you provided in the previous step)

Edit key

gpg --edit-key --expert real.name@barrage.net   

gpg (GnuPG) 2.2.19; Copyright (C) 2019 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. 
gpg: checking the trustdb 
gpg: marginals needed: 3  completes needed: 1  trust model: pgp 
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u 
sec  rsa4096/7C258D4980E4DCB5
     created: 2020-06-17
     expires: never
     usage: C  
     trust: ultimate      validity: ultimate
[ultimate] (1). Real Name <real.name@barrage.net>

Enter fullscreen mode Exit fullscreen mode

Insert addkey command to start the procedure for adding the second key

add key - RSA sign only

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? 4
Enter fullscreen mode Exit fullscreen mode

This step is similar to one from the creation of the first key, just on this step you choose 4 ( RSA - sign only ) and press enter

add key - RSA sign only - length

RSA keys may be between 1024 and 4096 bits long. 
What keysize do you want? (3072) 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) 1y 
Key expires at Thu Jun 17 09:44:10 2021 CEST 
Is this correct? (y/N) y 
Really create? (y/N) y
Enter fullscreen mode Exit fullscreen mode

It will again prompt you for keysize 4096 and for an expiration time. This time you input 1y meaning the key will expire in 1 year. On the next two prompts confirm creation with inputting y and pressing enter. Passphrase window will pop out requiring you to insert the passphrase which you have set up in 1st step.

Step 3 - generate RSA encrypt only key

This step is identical as previous (STEP 2) in every part besides selecting 6 (RSA - encrypt only) on first prompt. Afterwards key length is 4096, expiration time is 1y and confirm twice with y and passphrase on end

add key - RSA encrypt only

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? 6
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 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) 1y
Key expires at Thu Jun 17 09:46:10 2021 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, utilise the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec  rsa4096/7C258D4980E4DCB5
     created: 2020-06-17  expires: never       usage: C  
     trust: ultimate      validity: ultimate
ssb  rsa4096/6DCB9294B2139D96
     created: 2020-06-17  expires: 2020-06-17  usage: S  
ssb  rsa4096/40DDCC2E39087DC0
     created: 2020-06-17  expires: 2020-06-17  usage: E  
[ultimate] (1). Real Name <real.name@barrage.net>
Enter fullscreen mode Exit fullscreen mode

Step 4 - generate RSA authentication key

This step is kind of combination between step 1 and step 2.

Insert command addkey and press enter, on prompt enter 8 (RSA - set your own capabilities)

This time current allowed actions start with: Sign and encrypt; you need to toggle them out and toggle in authenticate capability. It can be done by inputting S to toggle out Sign capability, afterward E to toggle out encrypt capability and finally A to toggle in authenticate capability. When you have only Authenticate in current allowed actions input Q and press enter.

add key - RSA authentication

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? 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? s
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: 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 Encrypt Authenticate
Current allowed actions:
   (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: Authenticate
   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? q

Enter fullscreen mode Exit fullscreen mode

Afterward key length will be prompted - 4096 again, key expiration - 1y, confirm twice with y and enter passphrase. If you have done everything correctly something like this should appear

add key - RSA authentication - length

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 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) 1y
Key expires at Thu Jun 17 09:48:10 2021 CEST
Is this correct? (y/N) y
Really create? (y/N) y
Enter fullscreen mode Exit fullscreen mode

add key - RSA authentication - summary

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, utilise the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
sec  rsa4096/7C258D4980E4DCB5
     created: 2020-06-17  expires: never       usage: C  
     trust: ultimate      validity: ultimate
ssb  rsa4096/6DCB9294B2139D96
     created: 2020-06-17  expires: 2020-06-17  usage: S  
ssb  rsa4096/40DDCC2E39087DC0
     created: 2020-06-17  expires: 2020-06-17  usage: E   
ssb  rsa4096/23BA279F2C8D06F9
     created: 2020-06-17  expires: 2020-06-17  usage: A  
[ultimate] (1). Real Name <real.name@barrage.net>

gpg> save

Enter fullscreen mode Exit fullscreen mode

Last but not least, enter command save to finish your key creation process.

Step 5 - create backups

Run following commands to export keys

Provide passphrase where necessary.

create backups - commands

gpg --export-ownertrust > ~/.gnupg/backup_trustdb.txt
gpg --armor --export-secret-keys <your_email_address> > ~/.gnupg/secret_keys_<your_email_address>.asc
###(enter passphrase if prompted)
gpg --armor --export-secret-subkeys <your_email_address> > ~/.gnupg/secret_subkeys_<your_email_address>.asc 
###(enter passphrase if prompted)
Enter fullscreen mode Exit fullscreen mode

you can list keys with

list keys

ls -all ~/.gnupg/openpgp-revocs.d
Enter fullscreen mode Exit fullscreen mode

Step 6 - transport keys to yubikey

Insert yubikey into usb slot in your machine and write command

gpg --card-status

Enter fullscreen mode Exit fullscreen mode

to get data from your Yubikey. If it works it should provide with Yubikey related data.

Enter command

gpg --card-edit

Enter fullscreen mode Exit fullscreen mode

to be able to edit card data. Type command

verify
Enter fullscreen mode Exit fullscreen mode

and it will prompt you administrator pin.

Important: Default admin pin is 12345678.

You can use command

help

Enter fullscreen mode Exit fullscreen mode

to view all possible commands for your Yubikey.

When you are done you can type command

quit
Enter fullscreen mode Exit fullscreen mode

To insert keys into your yubikey run following commands and it will output like from the screen below:

gpg --edit-key --expert <your_email_address>

Enter fullscreen mode Exit fullscreen mode

Exporting keys to yubikey - list keys

gpg --edit-key --expert john.doe@barrage.net

gpg (GnuPG) 2.2.19; Copyright (C) 2019 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/7C258D4980E4DCB5
     created: 2020-06-17  expires: never       usage: C  
     trust: ultimate      validity: ultimate
ssb  rsa4096/6DCB9294B2139D96
     created: 2020-06-17  expires: 2020-06-17  usage: S  
ssb  rsa4096/40DDCC2E39087DC0
     created: 2020-06-17  expires: 2020-06-17  usage: E   
ssb  rsa4096/23BA279F2C8D06F9
     created: 2020-06-17  expires: 2020-06-17  usage: A  
[ultimate] (1). Real Name <real.name@barrage.net>

Enter fullscreen mode Exit fullscreen mode

To add the key you need to select it and transfer to Yubikey. If for example we typekey1 it will select 1st key and put * next to its ssb (like on picture below). Typing key 1 again will deselect that key

add key to yubikey - key 1

ssb* rsa4096/2C66AD4A15960BDB
     created: 2020-06-16  expires: 2021-06-16  usage: S
Enter fullscreen mode Exit fullscreen mode

Add 1st key (signature key)

Select 1st key with command: key 1

Write command: keytocard

When it prompts where to store, type : 1 (Signature key)

enter passphrase

enter admin pin

Add 2nd key (encryption key)

Deselect 1st key with command: key 1

Select 2nd key with command: key 2

Write command: keytocard

where to store: 2 (encryption)

enter passphrase

enter admin pin

Add 3rd key (authentication key)

Deselect 2nd key with command: key 2

Select 3rd key with command: key 3

Write command: keytocard

where to store: 3 (authentication)

enter passphrase

enter admin pin

Deselect 3rd key: key 3

Write command: save

gpg -k (list public keys)

gpg -K (list private keys)
Enter fullscreen mode Exit fullscreen mode

Important - You must change password and admin password on Yubikey for obvious security reasons

Enter edit mode with command: gpg --card-edit

Enter command: admin to allow admin commands

Enter command: passwd and following will be shown

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Enter fullscreen mode Exit fullscreen mode

Select 1 to change PIN

enter current pin (default: 123456)
enter new pin
confirm new pin
After you have finished PIN change it will give you the password menu again;

Select 3 to change Admin PIN

enter current admin pin (default: 12345678)
enter new pin
confirm new pin

Important: Save PIN, ADMIN PIN and PASSPHRASE to LastPass and protect access to them with LastPass master password

Step 7 - associate GPG with gitLab

Add GPG key in your gitlab settings

Export public key to clipboard with following command:

gpg --armor --export <your_email_address>  | pbcopy
Enter fullscreen mode Exit fullscreen mode

After that go to your gitlab site, click on your user button and click on settings in dropdown menu

Go to the GPG Keys section in the menu, paste your public key from clipboard into text area, press add keys and the result should look like this

Associate GPG key on your local machine to GIT repository

List your secret keys with following command

gpg --list-secret-keys --keyid-format LONG <your_email_address>
Enter fullscreen mode Exit fullscreen mode

List secret keys

sec   rsa4096/7C258D4980E4DCB5 2020-06-17 [C]
      DAF272D92DAE18C1790A1E8A7C258D4980E4DCB5
uid                 [ultimate] Real Name <real.name@barrage.net>
ssb  rsa4096/6DCB9294B2139D96 2020-06-17 [S] [expires: 2021-06-17]
ssb  rsa4096/40DDCC2E39087DC0 2020-06-17 [E] [expires: 2021-06-17]
ssb  rsa4096/23BA279F2C8D06F9 2020-06-17 [A] [expires: 2021-06-17]
Enter fullscreen mode Exit fullscreen mode

copy GPG key id that starts with ssb and has S next to date.

in this example → 6DCB9294B2139D96

Run the following commands to edit your local git configuration.

git config --global user.signingkey 6DCB9294B2139D96
Enter fullscreen mode Exit fullscreen mode
git config --global gpg.program gpg
Enter fullscreen mode Exit fullscreen mode
git config --global commit.gpgsign true
Enter fullscreen mode Exit fullscreen mode

Top comments (0)