YubiKey Neo with PGP subkeys post

I have been using PGP keys for some time, using them to sign and/or encrypt my e-mails (I use Mozilla Thunderbird with the Enigmail plugin for this).

I’ve been wanting to create a setup where I use these keys for more then just e-mail, for encrypting files or as SSH authentication for example. This also includes the ‘pass‘ tool, which utilizes a combination of git and pgp as a password manager in a powerful way.

As an owner of a YubiKey Standard ($25 and only for OTP purposes), I’ve known about the more expensive models (like the $50 YubiKey Neo), as I know of the existance of OpenPGP smartcards in the world. An important difference is, quite a few smartcards allow for only 1024bits keys, while the YubiKey allows 2048bit keys.

I went for the YubiKey Neo, got it in the mail, and started playing with it. I thought, might as well make a tutorial blogpost over this to help anyone who is considering such a setup.

First off, you need GnuPG installed, which is available in package-managers among Unix-like distro’s. I am demonstrating this on OSX, but should work fairly similar on other operating systems.

$ brew install gpg2

When first starting gpg, it will generate two things in your $GNUPGHOME directory (by default ~/.gnupg)

gpg: keyring `/Users/myusername/.gnupg/secring.gpg’ created

gpg: keyring `/Users/myusername/.gnupg/pubring.gpg’ created

gpg: /Users/myusername/.gnupg/trustdb.gpg: trustdb created

These files serve the basis of all keys GnuPG will deal with from this point on.

When first inserting the YubiKey and listing information from GnuPG, it will look something like this

$ gpg –card-status

Application ID …: D2760001XXXX000006036XXXXX0000

Version ……….: 2.0

Manufacturer …..: Yubico

Serial number ….: 036XXXXX

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]

Ofcourse, I’ve censored a few things here and there, but note the highlighted information. I can put three keys of 2048bit RSA on this device. Why are there three? And how do they differ?

Traditionally you can generate a PGP key and use it for whatever you like, signing, encrypting, authentication. Doesn’t really matter. Up until the point that your key may be compromised.

For prevent this, we are going to create a master key which can sign other keys, and three subkeys for Signing, Encryption and Authentication. The three subkeys will be integrated into the YubiKey, while the master key will live on an USB-stick stashed in a secret place.

To generate the master key, I’ve taken a bootable live debian image with no network attached, and mounted another USB-stick which I pointed out as the GNUPGHOME directory.

$ export GNUPGHOME=/media/user/USBSTICK/gnupghome

$ mkdir $GNUPGHOME

To generate the master key:

$ gpg –expert –gen-key

gpg (GnuPG/MacGPG2) 2.0.27; Copyright (C) 2015 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)

Your selection? 8

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

RSA keys may be between 1024 and 4096 bits long.

What keysize do you want? (2048) 4096

Requested keysize is 4096 bits

Please specify how long the key should be valid.

0 = key does not expire

= key expires in n days

w = key expires in n weeks

m = key expires in n months

y = key expires in n years

Key is valid for? (0) ****

Key does not expire at all

Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: Dennis de Greef

Email address: dennis@example.com

Comment:

You selected this USER-ID:

“Dennis de Greef dennis@example.com

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

You need a Passphrase to protect your secret key.

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, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

gpg: key AAB98B2F marked as ultimately trusted

public and secret key created and signed.

gpg: checking the trustdb

gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model

gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u

pub 4096R/AAB98B2F 2015-07-26

Key fingerprint = 69B2 F1E7 3A1F C011 D81C 802E 732D F32A AAB9 8B2F

uid [ultimate] Dennis de Greef dennis@example.com

So what we just did, was create an 4096bits RSA key with the only capability of signing other keys (we switched off Signing and Encryption). We set the expire date to never, since this key will forever be secret (stashed away somewhere). And if the key would somehow be compromised, we can use a revocation certificate (I’ll come back to that later).

It also asked for a passphrase, be sure to put in a strong password in here.

NOTE: Be sure to put in your valid e-mail address. If you want more e-mail addresses known, you can add them with adduid in the GPG edit-key mode.

Before proceeding, we want to create a backup of our master key to a plaintext format

$ gpg -a –export-secret-keys AAB98B2F > $GNUPGHOME/../masterkey.txt

$ cat $GNUPGHOME/../masterkey.txt

—–BEGIN PGP PRIVATE KEY BLOCK—–

Version: GnuPG/MacGPG2 v2

lQc+BFW0xnwBEADZ3q/nBuybiVZK9kbmoH2q3nccds0bS7l2iW4r7aT4Wm16z8RV

[…]

So, next we need to generate some subkeys to be able to perform the other capabilities.

$ gpg –expert –edit-key AAB98B2F

pub 4096R/AAB98B2F created: 2015-07-26 expires: never usage: C

trust: ultimate validity: ultimate

[ultimate] (1). Dennis de Greef dennis@example.com

gpg> addkey

Key is protected.

You need a passphrase to unlock the secret key for

user: “Dennis de Greef dennis@example.com

4096-bit RSA key, ID AAB98B2F, created 2015-07-26

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)

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? E

Possible actions for a RSA key: Sign Encrypt Authenticate

Current allowed actions: Sign

(S) Toggle the sign capability

(E) Toggle the encrypt capability

(A) Toggle the authenticate capability

(Q) Finished

Your selection? Q

RSA keys may be between 1024 and 4096 bits long.

What keysize do you want? (2048) 2048

Requested keysize is 2048 bits

Please specify how long the key should be valid.

0 = key does not expire

= key expires in n days

w = key expires in n weeks

m = key expires in n months

y = key expires in n years

Key is valid for? (0) 5y

Key expires at Fri Jul 24 13:45:33 2020 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, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

pub 4096R/AAB98B2F created: 2015-07-26 expires: never usage: C

trust: ultimate validity: ultimate

sub 2048R/A1EFF93C created: 2015-07-26 expires: 2020-07-24 usage: S

[ultimate] (1). Dennis de Greef dennis@example.com

gpg>

We now have created a subkey for signing. Repeat this process for Encryption and Authentication, and we have a master key with 3 subkeys for different capabilities. Type ‘save‘ to save your changes.

pub 4096R/AAB98B2F created: 2015-07-26 expires: never usage: C

trust: ultimate validity: ultimate

sub 2048R/A1EFF93C created: 2015-07-26 expires: 2020-07-24 usage: S

sub 2048R/4A71FF50 created: 2015-07-26 expires: 2020-07-24 usage: E

sub 2048R/77409C9F created: 2015-07-26 expires: 2020-07-24 usage: A

[ultimate] (1). Dennis de Greef dennis@example.com

It is good practice to generate a revocation certificate in case you lose your key. Store this in a safe place, possibly printed out on paper.

$ gpg –output $GNUPGHOME/../revocation-certificate.txt –gen-revoke AAB98B2F

sec 4096R/AAB98B2F 2015-07-26 Dennis de Greef dennis@example.com

Create a revocation certificate for this key? (y/N) y

Please select the reason for the revocation:

0 = No reason specified

1 = Key has been compromised

2 = Key is superseded

3 = Key is no longer used

Q = Cancel

(Probably you want to select 1 here)

Your decision? 1

Enter an optional description; end it with an empty line:

This revocation certificate is generated during key creation and should be used in emergencies only

>

Reason for revocation: Key has been compromised

This revocation certificate is generated during key creation and should be used in emergencies only

Is this okay? (y/N) y

You need a passphrase to unlock the secret key for

user: “Dennis de Greef dennis@example.com

4096-bit RSA key, ID AAB98B2F, created 2015-07-26

ASCII armored output forced.

Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets

access to this certificate he can use it to make your key unusable.

It is smart to print this certificate and store it away, just in case

your media become unreadable. But have some caution: The print system of

your machine might store the data and make it available to others!

Like the description says, store this away somewhere safe, and only use it when your master keys needs to be revoked.

Now we want to make a few backups in plaintext of our master key including the subkeys

$ gpg -a –export-secret-keys AAB98B2F > $GNUPGHOME/../mastersubkeys.txt

$ cat $GNUPGHOME/../mastersubkeys.txt

—–BEGIN PGP PRIVATE KEY BLOCK—–

Version: GnuPG/MacGPG2 v2

lQc+BFW0xnwBEADZ3q/nBuybiVZK9kbmoH2q3nccds0bS7l2iW4r7aT4Wm16z8RV

[…]

And for the subkeys

$ gpg -a –export-secret-subkeys AAB98B2F > $GNUPGHOME/../subkeys.txt

$ cat $GNUPGHOME/../subkeys.txt

—–BEGIN PGP PRIVATE KEY BLOCK—–

Version: GnuPG/MacGPG2 v2

lQIVBFW0xnwBEADZ3q/nBuybiVZK9kbmoH2q3nccds0bS7l2iW4r7aT4Wm16z8RV

Now we can setup the YubiKey to contain personal information and our subkeys. Make sure the device is in OTP/CCID or CCID mode.

$ brew install yubikey-personalization

$ ykpersonalize -m82

Now edit the card to personalise it.

$ gpg –card-edit

gpg/card> admin

Admin commands are allowed

gpg/card> passwd

gpg: OpenPGP card no. D2760001XXXX000006036XXXXX0000 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: De Greef

Cardholder’s given name: Dennis

gpg/card> lang

Language preferences: en

gpg/card> url

URL to retrieve public key: https://dennisdegreef.net/aab98b2f.txt

gpg/card> sex

Sex ((M)ale, (F)emale or space): m

gpg/card> login

Login data (account name): dennisdegreef

gpg/card> list

Application ID …: D2760001XXXX000006036XXXXX0000

Version ……….: 2.0

Manufacturer …..: Yubico

Serial number ….: 036XXXXX

Name of cardholder: Dennis De Greef

Language prefs …: en

Sex …………..: male

URL of public key : https://dennisdegreef.net/aab98b2f.txt

Login data …….: dennisdegreef

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

Next, we want to embed the subkeys into the card.

$ gpg –edit-key AAB98B2F

gpg (GnuPG/MacGPG2) 2.0.27; Copyright (C) 2015 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.

pub 4096R/AAB98B2F created: 2015-07-26 expires: never usage: C

trust: ultimate validity: ultimate

sub 2048R/A1EFF93C created: 2015-07-26 expires: 2020-07-24 usage: S

sub 2048R/4A71FF50 created: 2015-07-26 expires: 2020-07-24 usage: E

sub 2048R/77409C9F created: 2015-07-26 expires: 2020-07-24 usage: A

[ultimate] (1). Dennis de Greef dennis@example.com

gpg> toggle

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb 2048R/A1EFF93C created: 2015-07-26 expires: never

ssb 2048R/4A71FF50 created: 2015-07-26 expires: never

ssb 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> key 1

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb* 2048R/A1EFF93C created: 2015-07-26 expires: never

ssb 2048R/4A71FF50 created: 2015-07-26 expires: never

ssb 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> keytocard

Signature key ….: [none]

Encryption key….: [none]

Authentication key: [none]

Please select where to store the key:

(1) Signature key

(3) Authentication key

Your selection? 1

You need a passphrase to unlock the secret key for

user: “Dennis de Greef dennis@example.com

4096-bit RSA key, ID AAB98B2F, created 2015-07-26

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb* 2048R/A1EFF93C created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb 2048R/4A71FF50 created: 2015-07-26 expires: never

ssb 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> key 1

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb 2048R/A1EFF93C created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb 2048R/4A71FF50 created: 2015-07-26 expires: never

ssb 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> key 2

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb 2048R/A1EFF93C created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb* 2048R/4A71FF50 created: 2015-07-26 expires: never

ssb 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> keytocard

Signature key ….: EFA4 D5F7 95E0 4392 E42A 59CE DFE1 6372 72D2 245B

Encryption key….: [none]

Authentication key: [none]

Please select where to store the key:

(2) Encryption key

Your selection? 2

You need a passphrase to unlock the secret key for

user: “Dennis de Greef dennis@example.com

4096-bit RSA key, ID AAB98B2F, created 2015-07-26

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb 2048R/A1EFF93C created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb* 2048R/4A71FF50 created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> key 2

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb 2048R/A1EFF93C created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb 2048R/4A71FF50 created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> key 3

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb 2048R/A1EFF93C created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb 2048R/4A71FF50 created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb* 2048R/77409C9F created: 2015-07-26 expires: never

(1) Dennis de Greef dennis@example.com

gpg> keytocard

Signature key ….: EFA4 D5F7 95E0 4392 E42A 59CE DFE1 6372 72D2 245B

Encryption key….: A22D 5135 CCFC 947C 8925 9E77 A11F 46D4 35F4 CC42

Authentication key: [none]

Please select where to store the key:

(3) Authentication key

Your selection? 3

You need a passphrase to unlock the secret key for

user: “Dennis de Greef dennis@example.com

4096-bit RSA key, ID AAB98B2F, created 2015-07-26

sec 4096R/AAB98B2F created: 2015-07-26 expires: never

ssb 2048R/A1EFF93C created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb 2048R/4A71FF50 created: 2015-07-26 expires: never

card-no: 0123 00000042

ssb* 2048R/77409C9F created: 2015-07-26 expires: never

card-no: 0123 00000042

(1) Dennis de Greef dennis@example.com

gpg> save

$

NOTE: This article is a work in progress, we still need to send the keys to the keyserver, so everyone will know the public keys of our generated master key (which will validate all the subkeys as well).

Categories: Uncategorized