Creating Airgapped keys for Yubikey
Introduction
Before you begin, it would probably be a good idea to have three flash drives and a Yubikey.
- Your first USB stick will be a Live USB that will boot the airgapped system.
- The second will store the packages that you will need to install on the newly booted airgapped machine
- The last USB stick will hold the newly generated master key. It would probably be a good idea to store this stick in a safe
- Your Yubikey will hold a copy of your generated subkeys for use going forward
Purpose
The goal of this post is to document the process I used to add keys to my Yubikey, please do plenty of research before simply following this guide as best practices may have changed.
Booting up an airgapped machine
In this guide, as in the tutorial this is based on, we will be using an Ubuntu live USB.
When running on an Ubuntu machine, "Startup Disk Creator" can be used to make the live USB if you don't already have one created.
Downloading required packages
Before you can boot your live USB you need to download all the required packages and save them to one of the USB sticks.
To download the packages, the easiest way I found was to install the packages after connecting to the internet on the Live USB system. After saving the packages, reboot and this time rather than connecting to the internet, install the packages saved to the USB drive.
After starting up the live system and connecting to the internet:
Add the universe repository:
# add-apt-repository universe
Add the Yubikey ppa:
# add-apt-repository ppa:yubico/stable
Run update to download new package lists:
# apt update
Install packages with the "download-only" flag:
# apt-get --download-only install \ scdaemon yubikey-personalization \ libccid pcscd rng-tools gnupg2 ykpersonalize
Copy the files to USB drive, for example:
$ mkdir /media/usb/MyPackages $ cp -a /var/cache/apt/archives/*.deb /media/usb/MyPackages
Installing the packages
Reboot your live system after ensuring the computer is no longer connected to the internet (i.e. unplug any Ethernet cables)
Install the packages copied to the USB earlier:
# dpkg -i /media/usb/MyPackages
Generating keys
First start rngd to ensure computed has plenty of random bits available:
# rngd -r /dev/urandom
The default GPG workspace for GPG is ~/.gnupg. We can set this to something easier to work with by setting $GNUPGHOME.
$ export GNUPGHOME="$HOME/workspace" $ mkdir $GNUPGHOME
In this guide, we will generate one master key and three subkeys, each with a single responsibility:
- sign-only key
- encryption key
- authentication key
Generating master key
$ gpg2 --full-gen-key
Running this command will open a menu to configure options before creating the new key
- Select key type: Select (4) sign-only
- Choose the larger size (4096 bit.)
- Enter your personal information (name and email)
- Select an expiration date for the key
List public keys:
$ gpg2 --list-keys
List private keys:
$ gpg2 --list-secret-keys
Using the output from the above command, save the key id to a variable for use later, for example:
$ export KEYID=AD2A33A5833064D4065EF6D7AFC3D78A4CB7C59D
Generate a revocation certificate
Since we are going to kept the master key on a USB key in storage, it is a good idea to generate a revocation certificate while we have access to the master key.
$ gpg2 --output $GNUPGHOME/revocation-certificate.txt --gen-revoke $KEYID
Select option (1) "Key has been compromised" and add a comment when asked.
Creating subkeys
Generate sign-only subkey
$ gpg2 --expert --edit-key $KEYID
This should open up the builtin GPG REPL.
- Start sub key creation be running the "addkey" command
- Select option (4) Sign-only key
- Select your key size (Yubikey 4: 4096 and Yubikey Neo: 2048) and expiration date
- After this type y twice to confirm
- Lastly, type save to save changes and exit
Generate encryption subkey
$ gpg2 --expert --edit-key $KEYID
This should open up the builtin GPG REPL.
- Start sub key creation be running the "addkey" command
- Select option (6) RSA encryption only
- Select your key size (Yubikey 4: 4096 and Yubikey Neo: 2048) and expiration date
- After this type y twice to confirm
- Lastly, type save to save changes and exit
Generate authentication subkey
$ gpg2 --expert --edit-key $KEYID
This should open up the builtin GPG REPL.
- Start sub key creation be running the "addkey" command
- Select option (8) RSA set your own ability, and toggle the options until you see Current allowed actions: Authenticate
- Select your key size (Yubikey 4: 4096 and Yubikey Neo: 2048) and expiration date
- After this type y twice to confirm
- Lastly, type save to save changes and exit
Add additional email addresses to the key (optional)
$ gpg2 --edit-key $KEYID
This should open up the builtin GPG REPL.
- Running the "adduid" command
- Follow the prompts to enter your "Real name", "Email" and "Comment"
- After this enter o to confirm
- Lastly, type save to save changes and exit
Check the keyring
Listing keys should produce output like this now:
$ gpg2 --list-keys pub rsa4096 2018-06-23 [SC] [expires: 2023-06-22] 68207CD9783F93ECBFF9653640D9D08813E47FC4 uid [ultimate] Paul Schwendenman <schwendenman.paul@example.com> uid [ultimate] Paul Schwendenman <paul@example.org> sub rsa2048 2018-06-23 [S] [expires: 2023-06-22] sub rsa2048 2018-06-23 [E] [expires: 2023-06-22] sub rsa2048 2018-06-23 [A] [expires: 2023-06-22]
Export Public key
$ gpg2 -a --export $KEYID > public-key.asc
Copy your public key to a USB for later use, I'd recommend the one we used to store the air gapped packages.
Importing the public key on your machine later:
$ gpg2 --import < public-key.asc
Backing up master key to USB drive
Create a backup copy of your GNUPGHOME before adding subkeys to Yubikey:
$ cp -r $GNUPGHOME{,.bak}
Check connection to your Yubikey
Insert your Yubikey
Ensure that gpg is able to see your smart card:
$ gpg2 --card-status
Also check that the detected serial number matches the one on the key.
If your key is not present, you may need to restart pcscd:
$ sudo service pcscd restart
You may need to disable OTP on your Yubikey, I believe that newer Yubikeys are shipped configured to run all three modes (OTP, U2F and PGP) simultaneously. However, if you have issues perhaps look into enabling CCID or disabling OTP and deleting it from the configured slots using the yubikey-personalization tool.
Setting up your Yubikey
The Yubikey has two PINs. The admin pin is used to manage the user pin, and the user pin is used to manage access to the keys.
Change the admin pin (default: 123456678):
$ gpg --card-edit gpg/card> admin Admin commands are allowed gpg/card> passwd 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? 3
And then user pin (default: 123456):
1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? 1
You can now leave the passwd menu:
PIN changed. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection? Q
Be sure to write both pins down to be stored with the USB with your backed-up GPG key, since the pin can't be used to open the backed up GPG key, it is fine to store them together. Otherwise you'll have to repeat the moving key steps after resetting the Yubikey if you ever forgot the pins.
After changing both pins, change the other registration fields: "Name", "Login", "URL", etc. After changing the desired values, you can exit with quit.
For example, changing the name:
gpg/card> name Cardholder's surname: Schwendenman Cardholder's given name: Paul
To list fields and check your settings use the list command:
gpg/card> list Manufacturer .....: Yubico Name of cardholder: Paul Schwendenman Language prefs ...: en URL of public key : https://whatsdoom.com/40D9D08813E47FC4.txt Login data .......: paul
If you have a keybase account you can use it to host public keys, for example:
https://keybase.io/whatsdoom/key.asc
Obviously, you would have to add the newly created key to keybase using you public after you restart to your normal system at the end.
Enabling touch-only mode
If you have a Yubikey 4 (rather than a Neo), you can enable "touch-only" mode which requires a touch to return the result of crytographic operations.
Information can be found on Yubico's site.
Moving subkeys to Yubikey
Note moving keys is destructive ensure you have backed up the keys before proceeding.
Carefully add each key to the correct spot, the sequence should look something like:
$ gpg2 --edit-key $KEYID > key 1 > keytocard > 1 > key 1 > key 2 > keytocard > 2 > key 2 > key 3 > keytocard > 3 > save
Check that you have successfully moved you keys:
$ gpg2 --card-status
You should now see the key information in the output.
Next steps
You are now ready to use the Yubikey on you normal machine. Ensure that you have copied the backup directory (${GNUPGHOME}.bak) to your flash drive. After you have double checked that the backup directory was safely copied, you can restart you live system and boot the normal system.
On your normal machine, install the following packages to use your Yubikey:
sudo apt-get -y install scdaemon libccid gnupg2 pcsc-tools
Remember to use your yubikey, you'll need to import the public key in to the keyring.
$ gpg2 --import < public-key.asc
You can now use your key to sign git commits, send encrypted messages and ssh into remote machines!