How I configured YubiKey to sign and decrypt emails on Mac
18 June 2024
As you see on my "resume" page, I uploaded my public key for encrypting emails back when I was starting this website. However, moving private key from one place to another is never a good option. My YubiKey cost me 55€ and I barely use it for FIDO/U2F. Why not keep the private key in there and have it with me at all times?
Required software (for Mac)
We need some software on Mac to make this work. The process should be similar on Linux. Assuming you have brew installed, we will install the following packages:
$ brew install gnupg pinentry-mac ykman
I will also use Thunderbird as it integrates with
GnuPG directly (with a special cheat code you need to enter in settings). First
thing to do is to set up GnuPG to ask for PIN code using a GUI. We will use
pinentry-mac
as our input program and restart GPG Agent.
$ mkdir -p ~/.gnupg
$ touch ~/.gnupg/gpg-agent.conf
$ PINENTRY=$(which pinentry-mac)
$ echo "pinentry-program $PINENTRY" >> ~/.gnupg/gpg-agent.conf
$ gpgconf --kill gpg-agent
$ gpgagent --daemon
Setting up PIN on YubiKey
Now we can set our PIN codes on YubiKey for OpenPGP. You should do this and not
use factory default codes. The default Admin PIN is 12345678
and the default
PIN is 123456
. Don't forget them!
$ ykman openpgp access change-admin-pin -a 12345678 # Enter your new 8-digit Admin PIN
$ ykman openpgp access change-pin -P 123456 # Enter your new 6-digit PIN
Generating key pair on YubiKey
Now using GnuPG, we can interface with our YubiKey OpenPGP implementation to create a new key pair that will be safely stored on it.
$ gpg --card-edit
You will enter the gpg/card
prompt. Issue the following commands to the
YubiKey and enter PIN (not-admin) code when asked. Do not back up the key as it
is safer that way. Set some expiration date you like. Enter your name, email and
comment. Finish by giving the Admin PIN when asked.
gpg/card> admin
gpg/card> generate
Make off-card backup of encryption key? (Y/n) n
Key is valid for? (0) 2y
Real name: John Doe
Email address: john@example.com
Comment: my yubi pgp key
In case you want to use a different key size, before generate
command, type
key-attr
and select key type you want. Verify with Admin PIN.
Next export the public key to a file using GPG. Assuming that you don't have any
other keys in your keyring for the same e-mail address, you can write the
following. This will be the key you share with others. Otherwise you can run in
card edit mode of GPG list
and copy the key ID to export.
$ gpg --armor --export john@example.com > mypublickey.asc
$ gpg --import mypublickey.asc
$ gpg --list-keys
Look for the key ID you have just imported and save it. We will need it later. It will look something like:
pub rsa4096 2020-05-04 [SC] [expired: 2024-05-03]
THIS-IS-KEY-ID 01234ABCDEF01234...
uid [ultimate] My Name <johndoe@example.com>
Cross-signing with an old key
This step is optional. In case you have some previous key pair that you used for GPG, you can copy over the new public key to your old keyring and sign it with the old private key. This way, you can have unbroken chain of trust.
$ gpg --import mypublickey.asc
$ gpg --list-keys # Find your old and new key IDs
$ gpg --default-key OLDKEYID --sign-key NEWKEYID
$ gpg --armor --export NEWKEYID > mypublickey-signed.asc
Configuring Thunderbird
By default Thunderbird uses some internal GnuPG storage. We need to ask it to connect to the external GPG agent so that it can connect to our YubiKey.
Open Thunderbird. Add your e-mail account if you didn't already. Click the three
lines menu and select Settings
. Scroll down to the bottom of the General
page and click Config Editor...
.
Search for mail.openpgp.allow_external_gnupg
and double click on it to set it
to true
. Quit Thunderbird with ⌘Q and open it again.
Right click on the account name in the left panel and select Settings
. Select
End-to-End Encryption
section and click Add key
. Select
External through GnuPG
and enter the key ID. It won't show any confirmation if
that is correct, you will have to just try to use it.
Try sending encrypted e-mail to yourself with signature. Select Encrypt
and
OpenPGP
at the top. If you see a warning that there's no key to encrypt this
email, simply click Resolve
and import the public key you exported previously
(mypublickey.asc
).
When trying to send or open encrypted e-mail, the PIN dialog should pop up. Type the 6-digit PIN you set for the key.
The problem with this setup is that sometimes Thunderbird freezes when trying to
decrypt or sign the email. I need then to "Force Quit" it in Activity Monitor on
Mac. With touch policy enabled (ykman openpgp keys set-touch
) it is even more
problematic but sometimes it works. Once you enter the PIN for both decryption
and signing and don't disconnect the key, don't kill GPG agent and don't quit
Thunderbird, it should work smoothly.