XLADIUS

Blog

June 25, 2018 / by / In OPSEC

Using Yubikey as openPGP smart cards

Yubikey for PGP

Xladius takes the security of its clients very serious, and implements intricate systems to protect client data by any means.

PGP

Pretty Good Privacy or PGP is a popular program used to encrypt and decrypt email over the Internet, as well as authenticate messages with digital signatures and encrypted stored files. A massive “downside” of PGP is the key management. While there are some user-friendly tools that make public key management in GnuPG easy, keeping your private key save, can be a challenge. Should a workstation of an employee be compromised, it can be rather easy for an advanced attacker to gain control over the PGP private key and eventually decrypt the victims emails.

Yubikey

Yubikeys are commonly used to implement 2FA (Two Factor Authentication) over the web using FIDO U2F. This is an amazing feature, as Yubikeys are cheap, reliable, secure and easy to use. While FIDO U2F is the major selling point for Yubikeys, they also implement openPGP smartcard functionalities, which allows users to store their PGP private keys on these physical devices. Which protects the highly sensitive PGP private keys from attackers that have physical or code execution access to the users workstation. Yubikey openPGP smartcards integrate seamlessly into GnuPG and can therefore be used for all GnuPG based solutions like Enigmail or Keybase.

Use cases

Not only do we use Yubikeys to protect our employees cooperate email, there are countless other use cases where the use of PGP and Yubikeys can enhance data security to protect sensitive information and client data.

  • Yubikeys with gpg-agent can be used to authenticate against SSH servers
  • Xladius follows a very strict data retention policy. When projects are finalized, we encrypt project data the data with PGP and create 1 year backups. While the public key for project backups is known to all employees, the Yubikey that has the private key, is stored in a safe-deposit box.

Installation

Arch

To enable the USB access to Yubikey, implement following udev roles.

echo 'KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664",\
GROUP="users", ATTRS{idVendor}=="2581", ATTRS{idProduct}=="f1d0"' \
| sudo tee /etc/udev/rules.d/10-security-key.rules

In order for your YubiKey to be a U2F device and behave as a GPG card, you need to put the card into a mode called ‘super combo mode’. On Arch Linux, install yubikey-personalization and set the ‘super combo mode’ (86) like this:

pacman -S yubikey-personalization
ykpersonalize -m 86

Creating PIN and Admin PIN

To protect the openPGP smartcard functionality from attackers with access to the physical key, setup a PIN (usage to encrypt and sign) and Admin PIN (configuration changes).

gpg --card-edit

Application ID ...: D2760001240102000060000000420000
Version ..........: 2.0
Manufacturer .....: unknown
Serial number ....: 00000042
Name of cardholder: [not set]
Language prefs ...: [not set]
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> admin
Admin commands are allowed

gpg/card> passwd
gpg: OpenPGP card no. D2760001240102000060000000420000 detected

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 3
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? 1
PIN changed.

1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit

Your selection? q

gpg/card> name
Cardholder's surname: Barg
Cardholder's given name: Jon



gpg/card>

Application ID ...: D2760001240102000060000000420000
Version ..........: 2.0
Manufacturer .....: unknown
Serial number ....: 00000042
Name of cardholder: Jon Barg
Signature PIN ....: forced
Key attributes ...: 2048R 2048R 2048R
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

gpg/card> quit

Flashing the PGP key to the Yubikey

While it is possible to let Yubikey generate the private key, I prefer to generate the private key myself. This way I can create a backup saved on cold storage, which guarantees business continuity, should I lose the Yubikey.

Do generate the PGP key, I used a Linux live image on an airgapped machine:

Generate the master key

gpg --expert --full-gen-key
  • Select 8: RSA (set your own capabilities)
  • Select E to toggle off the Encrypt capability, which will leave you with only Sign + Certify.
  • Set a 4096 bit key size.
  • Set the expiration date.
  • Setup a UID.
  • Setup a passphrase.
  • The primary key is generated. Note your new key ID, as you’ll be needing it henceforth.

Add UIDs (Optional)

gpg --expert --edit-key <longid>

Use gpg> adduid to add as many UIDs or e-mail addresses as you need. Once you’re done, toggle to gpg> uid <#> and use the gpg> primary command to set the primary UID. Now we will generate subkeys for each additional capability to be transferred to the main smartcard designated for daily use.

Create the Encrypt key

gpg> addkey
  • Select 6: RSA (encrypt only).
  • Set a 4096 bit key size.
  • Set the expiration date.
  • The first subkey is generated.

Create the Authenticate key

gpg> addkey
  • Select 8: RSA (set your own capabilities)
  • Select S and E to toggle off the Sign and Encrypt capabilities.
  • Select A to toggle on the Authenticate capability and press Q.
  • Set a 4096 bit key size.
  • Set the expiration date.
  • The second subkey is generated.

Set trust level

By the way, you should probably set the public key to the ultimate trust level.

gpg> trust

Select 5 = I trust ultimately.

gpg> save

Save the key(s) you’ve been creating.

Add signatures

If you want to sign your new master key with a previous key that you’re transitioning from, then the time is now. How else will people know you’re not an impostor?

gpg -u <your_old_keyid> --sign-key <longid>

Generate revocation certificate

It’s a good idea to create a revocation certificate, in case the YubiKey is lost or your private key is somehow compromised.

gpg --output revoke.asc --gen-revoke <longid>

Backup everything

gpg --armor --output privkey.sec --export-secret-key <longid>
gpg --armor --output subkeys.sec --export-secret-subkeys <longid>
gpg --armor --output pubkey.asc --export <longid>

You can move these private keys plus the revocation certificate someplace safe, like an encrypted partition or offline storage media. As mentioned earlier, you can use gpg –card-edit to setup your smartcard: set the PINs, and variables like language, sex, your first and last name, or a public URL for downloading your key. So, after you’ve created keys, initialized the card and set new PINs, let’s import the keys.

Loading keys onto the smartcard

gpg --expert --edit-key <longid>
gpg> toggle
gpg> keytocard

Answer ‘y’ to “Really move the primary key?” Select 1: Signature key. Enter your passphrase and admin PIN as required.

gpg> key 1
gpg> keytocard

Select 2: Encryption key Enter your passphrase and admin PIN as required. Un-toggle key one: gpg> key 1 Toggle key two: gpg> key 2

gpg> keytocard

Select 3: Authentication key. Enter your passphrase and admin PIN as required. Un-toggle key two: gpg> key 2 gpg> save

Further Steps

You shouldn’t have to delete any secret keys, as they were moved to the smartcard. When you use either keytocard command or perform key generation on the card, GnuPG places a “stub” in your keyring so that it knows the actual secret key material is located on the smartcard. It appears as though you possess the secret key in your keyring but you actually don’t, and you can’t decrypt anything without the card. It’s just a stub pointing to the smartcard — which is something you do want to keep if you’d like this to be usable.

To delete the stubs:

gpg --armor --output stubs.asc --export-secret-keys <longid>

Yubikey OpenPGP Touch

In case you are using a Yubikey Nano, it is common to leave the Yubikey in the USB port of the notebook. In this case, it makes sense to add the touch functionality as an additional security feature. The Yubikey then only decrypts or signs with GnuPG if the user touched the Yubikey shortly.

This can be configured my moving the OTP functionality to Slot 2 using the yk-personalize tool and to map the Slot 1 (short touch) to OpenPGP. This can be done with ykman:

ykman openpgp touch enc on
ykman openpgp touch sig on

Importing Keys to keybase.io

It is also possible to import the keys to keybase.io.

keybase pgp select --multi