
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.
January 16, 2021
15 minBasic 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
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
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
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
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) <[email protected]>" Real name: Real Name E-mail address: [email protected] Comment: You selected this USER-ID: "Real Name <[email protected]>" Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? o
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 <[email protected]>
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>
(the address you provided in the previous step)
Edit key
gpg --edit-key --expert [email protected] 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 <[email protected]>
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
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
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 <[email protected]>
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
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
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 <[email protected]> gpg> save
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)
you can list keys with
list keys
ls -all ~/.gnupg/openpgp-revocs.d
Step 6 - transport keys to yubikey
Insert yubikey into usb slot in your machine and write command
gpg --card-status
to get data from your Yubikey. If it works it should provide with Yubikey related data.
Enter command
gpg --card-edit
to be able to edit card data. Type command
verify
and it will prompt you administrator pin.
Important: Default admin pin is 12345678.
You can use command
help
to view all possible commands for your Yubikey.
When you are done you can type command
quit
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>
Exporting keys to yubikey - list keys
gpg --edit-key --expert [email protected] 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 <[email protected]>
To add the key you need to select it and transfer to Yubikey. If for example we typekey 1it 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
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)
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
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
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>
List secret keys
sec rsa4096/7C258D4980E4DCB5 2020-06-17 [C] DAF272D92DAE18C1790A1E8A7C258D4980E4DCB5 uid [ultimate] Real Name <[email protected]> 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]
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
git config --global gpg.program gpg
git config --global commit.gpgsign true