Pretty Good Privacy (PGP) is an open standard for encrypting and signing data, including email, between two PGP users. In this guide, we’ll go through the process of securely generating, storing, and using a PGP key pair in a hardware token.
This guide is intended for readers familiar with using PGP who want to take an extra step in fortifying the security around their private key. Some of these steps also utilize a command-line interface, and it may be helpful to get comfortable with that interface before diving in.
In our previous introduction to PGP, we discussed what public and private key encryption are, and how to create a PGP key pair using Mailvelope, a web browser extension available for Chrome and Firefox. While this process is the easiest and most accessible way to get started using PGP, there are potential risks around depending on a web browser’s ability to securely store your keys—not to mention the security of the computer and its operating system.
A key concern in using PGP is keeping the private key used to decrypt or sign messages safe. Your PGP private key is made of a small chunk of text in a file on your computer. Unlike modern end-to-end encrypted communication apps such as Signal, PGP’s keys are static—they don’t change. What does that mean for you? If an adversary gets a hold of your PGP private key, it can be used to decrypt any existing email or files ever encrypted with your public key.
The more places with access to your private key, the greater the possibility of it being exfiltrated by a breach in the security mechanisms of your web browser, operating system, or even the computer hardware itself.
In addition to hacking, there’s also the question of where your key files may be copied when using a cloud backup service such as Microsoft’s OneDrive or Apple’s iCloud. When your private key lives in the cloud, you’re entrusting its protection to a third party.
Using a key pair on multiple computers introduces additional risk, as that increases the number of places something can go wrong. The risk of your computer itself being seized is also a concern because it may be possible to exfiltrate the private key with forensic tools.
PGP supports “smartcard” hardware, which allows you to decrypt and sign files and emails using the tiny chip encased in a supported smartcard device, without ever having to share the private key with the computer it’s connected to. Unlike using a file for a private key on your computer, smartcards are designed to protect their contents in ways that computers can’t. While general-purpose computers are designed to allow an ever-increasing combination of things to happen in their hardware, smartcards are typically designed to only allow a strict set of functions to run in only specific secure circumstances. This massively reduces the possibility of your private key falling into the wrong hands—however, the messages you’re decrypting are still being displayed on your computer. Keeping your computer's operating system and app updates up to date will help protect it from malware that could try to read your emails and files once they’re decrypted.
Speaking of good digital hygiene, this guide assumes you are creating a new key pair. To create and manage a new key pair safely it’s important to first create a reasonably secure environment. When PGP was first created, personal computers existed in a more isolated environment. They were truly personal, because what existed in their data storage usually stayed there and was only shared with another computer with their owners manually and consciously doing so. With the way our devices in the modern era are designed, both local and remote computers have copies of their contents, with cloud services—or malware quietly copying files we don’t even see—into parts unknown in the Cloud.
Of the files that should never exist outside the devices you own and control, your PGP private key is one of them. To ensure you know exactly where your key is, we should take some precautions against known risk factors.
Malware presents a similar technology risk but with different adversaries. Whereas a backup cloud service might create the vulnerability of lawful access to your files, malware presents the risk of unlawful access to your files.
Malware can find its way into your computer through a few different avenues, including unsolicited email attachments, USB drives of mysterious origin, or installing sketchy downloads. Modern Windows and Mac devices, however, have built-in defenses against the ability for malware to take hold. Every now and then, however, those security mechanisms are found to have vulnerabilities and can be breached. Run your software updates as often as you can.
In theory, a computer that only exists offline and never connects to the internet, an “air gap,” would offer the most complete possible protection against these risks, but creating an air gap is beyond the scope of this guide.
File syncing software such as iCloud or OneDrive, among others, are designed to copy the files you have on your computer into their cloud service, thus giving them the technical ability to access those files. If you use any cloud file sync or backup services, turn them off before going through this guide:
Windows OneDrive users:
Mac iCloud users:
There may be other file sync and backup services beyond OneDrive or iCloud to turn off sync for. Take note of any you may have running on your computer and check their documentation to learn how to turn off or pause them.
There are several manufacturers producing smartcard devices of every shape, and most don’t even look like cards at all! This guide uses Yubico's YubiKey 4 and was also tested with Nitrokey’s Nitrokey Pro but the same steps will be similar across other smartcard devices which support PGP. PGP in this case, will come in the form of Gnu Privacy Guard (GPG), a free, open source implementation of PGP available for Mac, Windows and Linux. In addition to a smartcard device, you’ll also need to download and install this software:
The Gpg4win software for Windows and GPG Suite software for Mac are distributed as a direct download rather than through a software package repository or app store. Because of this, you may want to manually verify the downloaded file’s integrity using special codes—“checksums" to make sure it hasn’t been tampered with between you and the website you’re downloading something from. One caveat to this process is that, ultimately, the downloaded software and checksum probably came from the same website. Although attacks on websites to modify downloads and checksums are extremely rare, easily detectable and usually addressed swiftly, they do sometimes happen. It may be advisable to wait a short while for any news to break on this kind of attack happening on either the Gpg4win or GPG Suite websites.
To learn how to use this SHA 256 checksum, check out our guide on verifying open source software to learn how.
After verifying your download, you’ll want to install the software you downloaded and create a new PGP key pair if you don’t already have one you want to migrate to a smartcard.
Once your new key pair is created, you’ll want to make a backup copy. While our aim is to have a PGP private key that only exists in your smartcard, sometimes smartcards break or need to be replaced with newer hardware, so it’s a good idea to have a backup copy in an offline location, like a USB drive in a locked safe. A password-encrypted USB drive adds an extra layer of protection, and can be created on a Mac with Disk Utility or VeraCrypt on either Windows or Mac. This is a password you should keep in a secure place, like on a piece of paper in the aforementioned safe or your password manager.
Once you have your USB drive ready, export both your public and private key to it.
In a worst-case scenario where your PGP private key is compromised, you can use a “revocation certificate” to revoke any copy of your compromised public key uploaded to a PGP key server. A revocation certificate has to be created before you lose your private key, and can be safely stored as a regular file on the USB drive where you store your backup key. The revocation certificate can only be used to mark a public key as revoked and cannot be used for signing or decrypting anything, so the risk of compromise for that file is lower than a private key, but still warrants being stored in a USB drive outside your computer.
Unfortunately, neither Gpg4win nor GPGTools have a modern interface for interacting with smartcards, so you’ll need to use a command line interface, which you may have briefly previewed when verifying your download’s checksum. The command line interface is unfamiliar to the vast majority of humanity, since it was designed for a time before graphical user interfaces. In order to set up your smartcard with PGP, however, you’ll have to use it.
Once you’re in Command Prompt or Terminal, you’ll be presented with an empty window leading to a blinking “prompt” where we’ll type our commands.
Each “command” is just a line of instructions you type in. After typing a command, press Enter or Return on your keyboard to run it, and the command line will display the result.
Plug your new smartcard into a free USB slot.
Note for macOS users: MacOS may mistake your smartcard for a keyboard. If you see a Keyboard Setup Assistant dialog appear, you can safely close it and move on with the guide.
Note for Windows users: The first time you plug in your smartcard, Windows will detect it and may try to install the driver software it needs to be able to communicate with it. After Windows is done installing the drivers, you may need to restart before moving on to the next step.
At the command line, run the “gpg --card-status” command and confirm you can see the smartcard is connected and accessible to GPG. The output should be similar to:
Reader ...........: Yubico Yubikey 4 OTP U2F CCID Application ID ...: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Version ..........: 2.1 Manufacturer .....: Yubico Serial number ....: XXXXXXXX Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: not forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
The Yubikey 4 we are using in this guide has 2 default PINs and a reset code option:
PIN: For normal use, `123456` by default. Also called a user PIN or regular PIN.
Admin PIN: For admin privileges, `12345678` by default. Also called a PUK.
Reset Code: Used in case you lose or forget your PINs and want to perform a reset and start over.
Before setting up the PINs for your smartcard, it is important to have a safe place to store them. A password manager will help you generate, store (and label) each of the three PINs (PIN, admin PIN, and reset code) we'll be setting up. Some of the commands we'll be using may "time out" abruptly and force you to start over in entering a new PIN if you take slightly too long to type it, so it is recommended that you choose what these three PINs will be ahead of time. If you do not write down your PINs (or preferably, store them in your password manager), you will risk forgetting them.
Important note: If you forget your PIN and enter an incorrect PIN when signing or encrypting something more than three times, you will be locked out of your smartcard, and you’ll need to use the admin PIN to reset the PIN. If you forget your admin PIN and enter an incorrect admin PIN more than three times, you’ll need to use the reset code to factory-reset the entire smartcard (which will wipe any PGP keys you have stored) and start over. If you forget the reset code, you may have to start over with a new smartcard.
Don’t forget to save and label your PINs and reset code in your password manager.
The PIN and admin PIN may contain up to 127 characters for the Yubikey 4 or 32 characters for the Nitrokey Pro and may include these characters:
The risk of a password breach here is substantially lower than one for any of the passwords we use to log into our devices or online services; smartcards are forged with hardware mechanisms which limit the amount of incorrect PIN attempts that can be entered. Because of this, the horse race of password cracking can go no further than three attempts at guessing either the PIN or admin PIN. After attempts at gaining access to the PIN and admin PIN fail, the device is locked and its secrets are irreversibly wiped.
The reset code is a less sensitive code, since, while it can wipe the keys off your smartcard, it cannot be used to decrypt or sign anything, so feel free to make it something easy to remember.
Now we'll configure the smartcard to use the new PINs.
When prompted, you will have to enter the default PIN (regular or admin, respectively) before entering the one you want to replace it with. If you type an incorrect PIN too many times, you will have to reset your smartcard and start over.
At the command line, run the “gpg2 --card-edit” command.
Note for Windows users: If you see a “gpg: can’t connect to the agent: IPC connect call failed” error after running “gpg2 --card-edit”, wait a few minutes for the gpg> prompt to appear, type “quit” and hit enter to exit the prompt, then try “gpg2 --card-edit” again.
$ gpg2 --card-edit Reader ...........: Yubico Yubikey 4 OTP U2F CCID Application ID ...: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Version ..........: 2.1 Manufacturer .....: Yubico Serial number ....: XXXXXXXX Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: not forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card>
At the gpg/card> prompt, run “admin” to enable administrative changes to your smartcard.
gpg/card> admin Admin commands are allowed
Next, run the “passwd” command, which will present a list of actions you can take.
gpg/card> passwd gpg: OpenPGP card no. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX detected 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection?
First, change the admin pin, so run “3.” A prompt will appear asking for the existing, default admin PIN (12345678). Enter that, then enter the PIN you want to change it to, in the prompt that follows.
Your selection? 3 PIN changed. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection?
Next, change the user pin, so run “1.” A prompt will appear asking for the existing, default PIN (123456). Enter that, then enter the PIN you want to change it to, in the prompt that follows.
Your selection? 1 PIN changed. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection?
Finally, change the reset code, so run “4.” You will be asked for the new admin PIN we just set up. Enter that, then enter the reset code you want to set, in the prompt that appears (there’s no default reset code).
Your selection? 4 Reset Code set. 1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit Your selection?
Now that the two PINs and reset code are set, run “q” to exit the passwd menu.
Your selection? q gpg/card>
Finally, exit from the gpg/card> prompt.
Next, we’ll want to move the private key pair we generated earlier into the smartcard. We’ll select it by using its unique long key ID, which is made of the last 16 characters in a PGP key’s fingerprint, which is the even longer, mathematically-derived identifier unique for every PGP key, such as "CEC6EF2B BA762BE5 C1345C87 DF258C11 C785858F", which we’ll use as an example.
$ gpg --expert --edit-key DF258C11C785858F gpg (GnuPG) 2.2.11; Copyright (C) 2018 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. sec rsa4096/DF258C11C785858F created: 2019-06-10 expires: 2021-06-10 usage: SC trust: ultimate validity: ultimate ssb rsa4096/709023A107E7BFEC created: 2019-06-10 expires: 2021-06-10 usage: E [ultimate] (1). Rose Duper <[email protected]> gpg>
With the gpg prompt open, run the “toggle” command to allow the ability to edit the key.
gpg> toggle sec rsa4096/DF258C11C785858F created: 2019-06-10 expires: 2021-06-10 usage: SC trust: ultimate validity: ultimate ssb rsa4096/709023A107E7BFEC created: 2019-06-10 expires: 2021-06-10 usage: E [ultimate] (1). Rose Duper <[email protected]> gpg>
Before moving your private key from your computer to your smartcard, it’s important to make sure you have the backup copy we made earlier. Once the private key gets in and the computer’s copy is removed in the process, there’s no way to get it back. This is why it’s important to follow through on the previous steps on making a backup copy.
You’ll notice there’s technically two keys listed: a primary key with the same long key ID that the public key has, and a subkey with its own long key ID. We’ll need to move both, one at a time, to the smartcard.
Let’s select the subkey and move it first. Computers begin counting (if one can call it that) at zero, so the second key, so run key 1 to select it.
gpg> key 1 sec rsa4096/DF258C11C785858F created: 2019-06-10 expires: 2021-06-10 usage: SC card-no: 0006 04901377 trust: unknown validity: unknown ssb* rsa4096/709023A107E7BFEC created: 2019-06-10 expires: 2021-06-10 usage: E [ unknown] (1). Rose Duper <[email protected]> gpg>
You’ll now notice there is a “*” in the line identifying the subkey. Now that we have it selected, let’s move it to the smartcard by running the “keytocard” command.
gpg> keytocard Please select where to store the key: (2) Encryption key Your selection?
The “usage” attribute for this key was set to Encrypt (E) when it was created. Run “2” to select Encryption key.
Your selection? 2 sec rsa4096/DF258C11C785858F created: 2019-06-10 expires: 2021-06-10 usage: SC card-no: 0006 04901377 trust: unknown validity: unknown ssb* rsa4096/709023A107E7BFEC created: 2019-06-10 expires: 2021-06-10 usage: E [ unknown] (1). Rose Duper <[email protected]> gpg>
Next, we’ll move on to the primary key by running key 0 to select it.
gpg> key 0 sec rsa4096/DF258C11C785858F created: 2019-06-10 expires: 2021-06-10 usage: SC card-no: 0006 04901377 trust: unknown validity: unknown ssb rsa4096/709023A107E7BFEC created: 2019-06-10 expires: 2021-06-10 usage: E [ unknown] (1). Rose Duper <[email protected]> gpg>
When the primary key is selected, no “*” is displayed. This “design” decision may make it confusing to tell if anything is selected. In this case, the primary key is always selected by default when no subkey is selected otherwise. With the gpg prompt open, run the “keytocard” command and confirm with “y” when asked to.
gpg> keytocard Really move the primary key? (y/N) y Please select where to store the key: (1) Signature key (3) Authentication key Your selection?
Run “3” to choose the authentication key, which will give your smartcard the ability to sign files and messages.
Your selection? 3 sec rsa4096/DF258C11C785858F created: 2019-06-10 expires: 2021-06-10 usage: SC trust: ultimate validity: ultimate ssb rsa4096/709023A107E7BFEC created: 2019-06-10 expires: 2021-06-10 usage: E [ultimate] (1). Rose Duper <[email protected]> gpg>
Finally, run the “save” command to save your changes and exit the gpg prompt.
Congratulations! You now have PGP set up with your smartcard. Just like any security practice though, what’s tested in hypothetical scenario does not always match up with the chaos of reality. Being able to access encrypted messages is ultimately as important as making sure they’re confidential, and in the real world, people sometimes lose physical objects. (Ever lost your wallet?)
Because your private key is in a separate device and the only other place your private key exists is in a backup drive somewhere, anyone seizing your computer will not have what they need to decrypt messages or files encrypted with your private key. Chances are though, you’ll want to use PGP on a replacement computer. Luckily, there’s only a few small steps involved:
After this, you’ll want to run a command on the new computer to re-generate the “stubs” which allow your computer’s PGP keyring to interface with your smartcard.
Plug in your smartcard and run this command:
After running this command, you should see a list of keys on the card.
Reader ...........: Yubico Yubikey 4 OTP U2F CCID Application ID ...: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Version ..........: 2.1 Manufacturer .....: Yubico Serial number ....: XXXXXXXX Name of cardholder: [not set] Language prefs ...: [not set] Sex ..............: unspecified URL of public key : [not set] Login data .......: [not set] Signature PIN ....: not forced Key attributes ...: rsa2048 rsa4096 rsa4096 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 Signature key ....: [none] Encryption key....: E2D5 5741 740E 706D 363A 3FC2 7090 23A1 07E7 BFEC created ....: 2019-06-10 22:52:57 Authentication key: CEC6 EF2B BA76 2BE5 C134 5C87 DF25 8C11 C785 858F created ....: 2019-06-10 22:52:57 General key info..: sub rsa4096/709023A107E7BFEC 2019-06-10 Rose Duper <[email protected]> sec> rsa4096/DF258C11C785858F created: 2019-06-10 expires: 2021-06-10 card-no: 0006 04901377 ssb> rsa4096/709023A107E7BFEC created: 2019-06-10 expires: 2021-06-10 card-no: 0006 04901377
Although your private key is protected by a PIN code on your smartcard, there is still a chance an attacker may correctly guess it, so the standard procedure is to revoke the existing key with the revocation certificate created earlier. After that, you can start this guide over, generate a new key pair, and move it to a new smartcard.
If your smartcard has been run over by a particularly heavy vehicle, chewed and scratched by a ferret, or lost at the bottom of the ocean, but not in the hands of a potential adversary, then it may be okay to restore your key pair from the backup USB drive created earlier, then follow the instructions to move it into a new smartcard.