• Home
  • Blog
  • Figuring out GPG, SSH and U2F with YubiKey 4

Figuring out GPG, SSH and U2F with YubiKey 4

Vincent Danen

February 11, 2017

You know your wife is a keeper when she gets you a YubiKey 4 for your birthday! I was really excited about this YubiKey because of its support for storing your GPG private keys and also for an SSH private key, in addition to the U2F (Universal 2nd Factor) support. I've been using earlier versions of the YubiKey for OTP (one-time password) and U2F, but the new version was especially interesting to me because of the GPG support.

Plus it's a new toy to tinker with, and I like nerdy little things like this.

When I got it, it was easy enough to associate it with the accounts I previously had my U2F-only YubiKey associated with and also others I previously had not and probably should have.

However, when it came to getting this setup for GnuPG I ran into some interesting things. First off, I used this YubiKey Guide to get things setup (this is a great guide). I did it on my Fedora laptop because from the things I read it seemed that using Linux for the setup would be easier.

That guide is pretty Debian-specific when it comes to the software install, so on Fedora you want to use:

$ sudo dnf install ykpers libyubikey gnupg2 gnupg2-smime pcsc-list pcsc-lite-ccid

Creating the new key on the laptop was easy enough with the instructions provided but I ran into problems writing the keys to the YubiKey. I could program the card as root, but as the user that generated the key I was unable to write the keys. With a bit more hunting around, I found another blog post about using the YubiKey Neo as a GPG Smartcard for SSH Authentication and realized I needed to give myself access to write to the card via udev.

Editing the /usr/lib/udev/rules.d/69-yubikey.rules file to add myself as an owner of the device did the trick and now it looks like:

ACTION!="add|change", GOTO="yubico_end"

# Udev rules for letting the console user access the Yubikey USB
# device node, needed for challenge/response to work correctly.

# Yubico Yubikey II
ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010|0110|0111|0114|0116|0401|0403|0405|0407|0410", \
    OWNER="[me]", ENV{ID_SECURITY_TOKEN}="1"

LABEL="yubico_end"

Then reloading the configuration using:

$ sudo udevadm control --reload
$ sudo udevadm trigger

Now I could finish with the original tutorial and get the keys written to the card. Success!

Or so I thought. Once this was done, the U2F logins were no longer working. Plugging the YubiKey into my mac and trying to use it as the second factor with some of the sites it previously worked with was no longer possible.

Given this was already a few hours of work, I went off to eat dinner and watch a show with the family. When that was done, as often happens when you give your mind something else to think about, it occurred to me that the command in the original tutorial about changing the mode of the YubiKey might have had something to do with it. The original tutorial indicates that to configure the YubiKey you needed to do:

$ ykpersonalize -m82

Checking out the manpage, it seems that this mode of 82 sets:

  • MODE_FLAG_EJECT (which is the 80)
  • OTP/CCID composite device (which is the 2)

I guess earlier YubiKeys did not enable CCID which is what we need for GPG support. But guess what's missing? Right, the U2F support. We need mode 6, which is for OTP/CCID/U2F. So running:

$ ykpersonalize -m86

fixed the problem and now U2F works again (as does GPG).

The next problem I had was that, while GPG worked fine on my Fedora laptop, when I tried to do gpg2 --list-secret-keys on my mac, it was telling me there were no secret keys. Using gpg2 --card-status or gpg2 --card-edit worked fine, and they even showed those card slots occupied.

What the heck?!?

Well, it turns out GPG 2.1 uses a different format for storing key information that GPG 1.x and 2.0 don't support or understand. And MacGPG2 for the mac is currently providing 2.0.30 which didn't understand this stuff. And it turns out that fink (which I use for all the extra Linux-like commands and updated CLI tools that I like) did not provide GnuPG 2.1. As a result I switched from fink to HomeBrew because it provides GnuPG 2.1, which I found from Yubikey, GnuPG 2.1 Modern, and SSH on macOS.

There's still some work to be done to clean a few things up. I need to publish my new GPG key once I'm confident with it, and have signed it with my existing key, and revoked the old key. Then I need to put the new SSH pubkey on those servers that are critical and I want the higher security on.

Most of what I had to do to get this setup was already out there (thank you citizens of the internet!) but there were a few gotchas that others may stumble on and since I couldn't easily find any answers (maybe I'm the only one that tripped over the ykpersonalize, or maybe most people use these for GPG/SSH and not also U2F, I have no idea). Hopefully this will be helpful for anyone stuck in the same boat.

Quick notes on some macOS-specific things:

I'm a MailMate user (awesome email client) but the suggestion of using a command-line pinentry program causes it to crash because it can't get input from anywhere. You want to brew install pinentry-mac first, and then use that as the pinentry program for the gpg-agent. My ~/.gnupg/gpg-agent.conf file now looks like this:

enable-ssh-support
use-standard-socket
pinentry-program /usr/local/bin/pinentry-mac
default-cache-ttl 600
max-cache-ttl 7200

You will also want to uninstall MacGPG2 if you have it installed. You can re-install it if you want, as it does have some nice tools, but if you do be sure to select "Customize" on the installer and de-select "GPGMail" and "MacGPG2" (basically install "GPGServices", "GPGKeychain", and "GPGPreferences" only). I don't know if the GPGMail plugin will work with GnuPG 2.1 (I don't use Apple Mail and MailMate doesn't need it) so maybe you don't need to remove it (and I can't be bothered to find out).

As a final note, I had this working fine with two macs and my Fedora laptop, but when I tried it on another mac a day or two later it did not want to work. I finally figured out that it was because when I started fiddling with this, on the first two macs I had gnupg 2.1.17 but on the other mac it pulled the new version (2.1.18) from homebrew. This new version does not play well with the YubiKey. I filed this bug against homebrew but then after some more digging I found it was actually this upstream bug so hopefully 2.1.19 will fix the problem. I note it here only because it had me scratching my head for a few days going through my setups wondering if I had done something wrong on the last mac. Once I installed 2.1.17 on that one, everything worked peachy. Talk about whacky timing!

Thanks Ang for this awesome birthday present! =)

EDIT: see Replaced GPG Key for details on the new key.

Vincent Danen
February 11, 2017 @ 4:42 PM

One other thing I discovered if you're using MailMate. Based on this message to the mailmate mailing list (https://lists.freron.com/mailmate/2015-April/004210.html) you will want to execute:

defaults write com.freron.MailMate environmentVariables -array '{ enabled = :true;  name = "MM_GPG"; value = "/usr/local/bin/gpg2"; }'

As by default it looks for the MacGPG2 binary (although this seems to be a bit unpredictable and random, so while it might work "out of the box" if it doesn't, the above should do the trick).

Ben
January 13, 2018 @ 10:45 AM

Looking to do the something similar and wondering how things have stood up against time for about a year or so now for you. With this setup, when you want to sign or encrypt a message in MailMate do you insert your yubikey and then get prompted for your passphrase? Is that behavior based on what you have in your local .gnupg/gpg.conf file? When I installed MailMate I want to say that I just created a empty directory and symlink for the /usr/local/MacGPG2/bin/gpg2 command back to my homebrew maintained /usr/local/bin/gpg

Vincent Danen
January 24, 2018 @ 6:37 PM

Yeah, you need to have your yubikey inserted if you want to sign, encrypt or decrypt. You don't need to symlink (and IIRC that won't work)... you need to do the defaults write com.freron.MailMate command noted in the first comment. That will point it to the right place (just set the right path to the gpg binary you want to use). Works like a champ.

Everything else should work as-is noted in the article.

Leave a Comment

Comments use MarkDown. Need help? MarkDown Cheatsheet