|
@@ -0,0 +1,138 @@
|
|
1
|
+---
|
|
2
|
+date: 2016-08-11
|
|
3
|
+strapline: With bonus completely over-the-top security
|
|
4
|
+thumbnail: /res/images/yubikey/keys.thumb.png
|
|
5
|
+title: Creating an offline GnuPG master key with Yubikey-stored subkeys
|
|
6
|
+url: /2016/08/11/offline-gnupg-master-yubikey-subkeys/
|
|
7
|
+---
|
|
8
|
+
|
|
9
|
+<div class="image left">
|
|
10
|
+ <img src="/res/images/yubikey/keys.png" alt="Two yubikeys">
|
|
11
|
+</div>
|
|
12
|
+
|
|
13
|
+I recently noticed that I'd accidentally lost my previous GPG private key — whoops. It was on
|
|
14
|
+a drive that I'd since formatted and used for a fair amount of time, so there's no hope of
|
|
15
|
+getting it back (but, on the plus side, there's also no risk of anyone else getting their hands on
|
|
16
|
+it). I could have created a new one in a few seconds and been done with it, but I decided to treat
|
|
17
|
+it as an exercise in doing things properly.
|
|
18
|
+
|
|
19
|
+### Background: GPG? Yubikey?
|
|
20
|
+
|
|
21
|
+GPG or GnuPG is short for [Gnu Privacy Guard](https://www.gnupg.org/), which is a suite of
|
|
22
|
+applications that provide cryptographic privacy and authentication functionality. At a basic level,
|
|
23
|
+it works in a similar way to HTTPS certificates: each user has a public key which is shared widely,
|
|
24
|
+and a private key that is unique to them. You can use someone else's public key to encrypt messages
|
|
25
|
+so only they can see them, and use your own private key to sign content so that others can verify
|
|
26
|
+it came from you.
|
|
27
|
+
|
|
28
|
+A [Yubikey](https://www.yubico.com/faq/yubikey/) is a small hardware device that offers two-factor
|
|
29
|
+authentication. Most Yubikey models also act as smartcards and allow you to store OpenPGP
|
|
30
|
+credentials on them.
|
|
31
|
+
|
|
32
|
+<!--more-->
|
|
33
|
+
|
|
34
|
+### Introducing subkeys
|
|
35
|
+
|
|
36
|
+GnuPG supports subkeys, which provide fairly significant security advantages. Instead of just having
|
|
37
|
+a single public and private key, you have a master pair and then any number of subkey pairs. The
|
|
38
|
+subkeys are automatically associated with the master key, but they can be revoked independently.
|
|
39
|
+
|
|
40
|
+Having a master key fall into the wrong hands is a problem — you have to revoke the whole
|
|
41
|
+thing (assuming you have access to a revocation certificate) and start again, convincing everyone
|
|
42
|
+else that your new key is the "real" you. With subkeys, you can issue a revocation signed with your
|
|
43
|
+master key and then sign some new subkeys. There's no loss of trust, and as long as people refresh
|
|
44
|
+your key from a keyserver, everything carries on as normal.
|
|
45
|
+
|
|
46
|
+The other advantage to using subkeys is that you can keep the master key elsewhere. It doesn't
|
|
47
|
+need to be routinely accessible, and using it doesn't require access to the Internet. The master
|
|
48
|
+key is kept offline, significantly reducing the risk of anything bad happening to it.
|
|
49
|
+
|
|
50
|
+### Setting up a secure environment
|
|
51
|
+
|
|
52
|
+My main desktop runs Windows, and most of my other devices are work ones which come with automatic
|
|
53
|
+backups and network mounts that I don't fully grok. Neither of those is a particularly good option
|
|
54
|
+if I want to do something security sensitive.
|
|
55
|
+
|
|
56
|
+[Tails](https://tails.boum.org/) is the defacto choice for a secure, live linux system, so I went
|
|
57
|
+through their installation process and eventually ended up with a USB drive that can boot into
|
|
58
|
+Tails. The installation process from Windows is slightly convoluted, as it involves creating a
|
|
59
|
+bootable Tails image, then booting to that and using the Tails installer to create the real image
|
|
60
|
+on a different drive. If you're starting on a Linux box, you can just use the Tails installer
|
|
61
|
+directly instead of doing the two-drive shuffle.
|
|
62
|
+
|
|
63
|
+Just to be completely paranoid, I disconnected my PC from the network before booting Tails. This
|
|
64
|
+is known as [air-gapping](https://en.wikipedia.org/wiki/Air_gap_(networking)), and is done to
|
|
65
|
+eliminate the possibility of a remote attacker doing something to your system. Ideally the machine
|
|
66
|
+would never have been connected to the network, but I didn't happen to have an unused machine
|
|
67
|
+laying around.
|
|
68
|
+
|
|
69
|
+The final thing I needed was a secure place to store my master key. I opted for an
|
|
70
|
+[IronKey](http://www.ironkey.com/en-US/) — a hardware-encrypted USB drive that self-destructs
|
|
71
|
+if there are too many unsuccessful attempts to access it. It works out-of-the-box on both Windows
|
|
72
|
+and Linux, presenting a small unencrypted drive with software to run to interact with the secure
|
|
73
|
+partition.
|
|
74
|
+
|
|
75
|
+### Creating the keys
|
|
76
|
+
|
|
77
|
+Now I had a nice over-the-top setup it was time to actually the keys. There is [an excellent
|
|
78
|
+guide by Simon Josefsson](https://blog.josefsson.org/2014/06/23/offline-gnupg-master-key-and-subkeys-on-yubikey-neo-smartcard/)
|
|
79
|
+that walks through the entire process of creating the master key, creating three subkeys, and
|
|
80
|
+then transferring them to a Yubikey.
|
|
81
|
+
|
|
82
|
+The only point where I had to deviate from Simon's guide was setting the machine up to work with
|
|
83
|
+the Yubikeys. I was setting up two keys (a nano and a neo), and one just worked out of the box
|
|
84
|
+with the version of `libykpers-1-1` that was in Tails' apt repository. The other needed a slightly
|
|
85
|
+newer version but that was also available in apt and can be selected by specifying the version
|
|
86
|
+manually as pointed out in [this GitHub issue](https://github.com/freedomofpress/securedrop/issues/1035#issuecomment-140172267).
|
|
87
|
+The version numbers have since changed, but `apt-policy` makes it easy to figure out what's needed.
|
|
88
|
+As I was using an air-gapped system this process was a bit more complicated than it sounds,
|
|
89
|
+involving several USB drive transfers.
|
|
90
|
+
|
|
91
|
+After finishing the guide, I had my master key and a pre-generated revocation certificate stored
|
|
92
|
+securely on my IronKey, and the three subkeys stored on each Yubikey. Time to go back to Windows.
|
|
93
|
+
|
|
94
|
+### GPG, Windows and SSH
|
|
95
|
+
|
|
96
|
+Now with the IronKey disconnected and the master key out of harms way, it's time to go back to
|
|
97
|
+Windows. I downloaded the [GnuPG Modern](https://www.gnupg.org/download/) distribution and
|
|
98
|
+followed the instructions at the end of Simon's guide to import my public key and make GPG aware
|
|
99
|
+of the subkeys on the Yubikey. After that [Enigmail](https://www.enigmail.net/index.php/en/)
|
|
100
|
+was able to sign and encrypt e-mail in Thunderbird.
|
|
101
|
+
|
|
102
|
+<figure class="image left">
|
|
103
|
+ <img src="/res/images/yubikey/wisdom_of_the_ancients.png" alt="XKCD: Wisdom of the ancients">
|
|
104
|
+ <figcaption><a href="https://xkcd.com/979/">XKCD #979: Wisdom of the ancients</a></figcaption>
|
|
105
|
+</figure>
|
|
106
|
+
|
|
107
|
+Next up, I enabled PuTTy support and started the GPG agent, as documented over on
|
|
108
|
+[Yubico's site](https://developers.yubico.com/PGP/SSH_authentication/Windows.html). This allows
|
|
109
|
+you to use the authentication GPG key to authenticate SSH sessions from PuTTy. To find the
|
|
110
|
+SSH key you need to add to `.authorized_keys`, simply run `gpg --export-ssh-key`. At first I
|
|
111
|
+could SSH into a host but not use agent forwarding. After lots of unsuccessful Googling, I realised
|
|
112
|
+that GPG couldn't access the key anymore locally. Another quick search and I found a
|
|
113
|
+[forum thread](http://forum.yubico.com/viewtopic.php?f=35&t=2231) where someone had the same
|
|
114
|
+issue and found it was a problem with exclusive access to the card. They even passed on their
|
|
115
|
+wisdom and updated the thread with a solution, which got everything working for me.
|
|
116
|
+
|
|
117
|
+### VMWare
|
|
118
|
+
|
|
119
|
+I have a Ubuntu image running inside VMWare on my desktop that I use for most development
|
|
120
|
+activities. I'm unlikely to want to sign e-mail, but I probably want to sign commits (especially
|
|
121
|
+now that [GitHub exposes verified signatures](https://github.com/blog/2144-gpg-signature-verification)).
|
|
122
|
+
|
|
123
|
+To do that I need to pass the Yubikey through to the virtual machine. In its default configuration,
|
|
124
|
+VMWare recognises the Yubikey device but doesn't pass it through correctly. You need to configure it
|
|
125
|
+to [allow HIDs](http://www.timothysalmon.com/2014/12/vmware-workstation-connect-yubikey-to.html),
|
|
126
|
+after which `gpg --card-status` starts working from the VM.
|
|
127
|
+
|
|
128
|
+Unfortunately passing through the device makes it exclusively available to the VM so the host OS
|
|
129
|
+can no longer use it. As I have two Yubikeys, I just configured VMWare to ignore the nano key that's
|
|
130
|
+always plugged in, and pass through the neo when I plug that in. While swapping the configuration
|
|
131
|
+around, I found out that GPG remembers the ID of the smartcard that store credentials - if you
|
|
132
|
+swap the two keys with identical subkeys it demands the other one is reinserted. You can get rid of
|
|
133
|
+the references to the previous card using `gpg --delete-secret-keys`.
|
|
134
|
+
|
|
135
|
+### In conclusion...
|
|
136
|
+
|
|
137
|
+... I have a <a href="/16402FE2.txt">new PGP key</a> you can use to verify things I sign or encrypt
|
|
138
|
+messages to me.
|