OpenPGP - The almost perfect key pair
Guide to create the almost perfect OpenPGP keys
Summary
We saw in the previous article the generation of OpenPGP keys. As a reminder, we have in our keychain private keys:
wilson@spaceship:~$ gpg2 --list-secret-keys sec# rsa4096/1A8132B1 2017-10-05 [C] [expires: 2018-10-05] uid [ultimate] Wilson Eleven <wilson.eleven@labs.com> ssb rsa4096/B73A9C79 2017-10-05 [E] [expires: 2018-10-05] ssb rsa4096/9CC8B2FB 2017-10-05 [S] [expires: 2018-10-05] ssb rsa4096/8047B454 2017-10-05 [A] [expires: 2018-10-05]
We also exported the keys in files:
With this configuration, we have an effective strategy against theft or loss of the private key that is used for certification. If an attacker take the computer, he will not be able to certify another key. However, the private keys that allow to sign, encrypt and authenticate are still present on the computer. So, in case of the theft of the keys, it would be possible to sign messages during a certain time (the time that the stolen subkey is revoked).
To counter this attack, it is possible to place private keys in a smart card. These devices are very resistant to key extraction techniques. In addition to physical attacks, there is a pin code with 3 tries only. Then it's locked.
We will see in this article the export of the private keys of the subkeys in a smart card. For this example, I will use a Yubikey 4.
Yubikey is a device the size of a classic USB key. This key makes it possible to perform double authentication on website, such as Google or Github. Thus, if a person is in possession of both the email and the password of the victim, the attacker will not be able to connect without this usb key. This is the principle of double authentication, you must be in possession of two secrets.
Yubikey implements an open protocol: universal 2nd factor.
In addition to this main protocol, it supports others: OpenPGP, TOTP, HOTP, challenge-response.
The one that will interest us is OpenPGP.
I recommend you go through the official store to ensure the origin of the product. We are on products related to safety, it's important to know where the purchased product comes from.
For those who have a Github account, there is a promotional offer that allows to have -10% on the cart. Interesting :). However, it's valid only once. I recommend you order at least 2 products. The second will be useful to make a backup in the unfortunate event of the loss of the first one.
Last but not least, our OpenPGP key was generated with a size of 4096 bits. Only the version 4 of the Yubikey allows to save keys of this size. Version 3 and NEO only support keys up to 3072 bits.
As a reminder, we started our generation of OpenPGP key with a machine running Ubuntu 16.04 and GnuPG 2.1.11. To be able to export the keys to the Yubikey, we need to install additional tools beforehand.
wilson@spaceship:~$ sudo apt-get install -y gnupg-agent pinentry-curses scdaemon pcscd yubikey-personalization libusb-1.0-0-dev
Before using the Yubikey, check that the warranty tape has not been broken. If so, do not use it.
Insert the Yubikey into a USB port and type the following command to verify that the card is well recognized.
wilson@spaceship:~$ gpg2 --card-status
Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006064764950000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 06476495
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 card is blank, there is no personal information. It is recommended to supplement the information in case a nobody would find this key.
Edit the card and switch to admin mode. You can enter help
to get the list of available commands.
wilson@spaceship:~$ gpg2 --card-edit gpg/card> admin Admin commands are allowed
First of all, we'll change the PIN key administration code and user PIN. By default, the administrator PIN is 12345678 and the user PIN is 123456.
The administrator PIN is required for some operations on the card, such as the key export, and to unlock when a PIN code has been entered 3 times by mistake.
Enter passwd
to change them. Let's start with the administrator PIN and then the user PIN.
gpg/card> passwd
gpg: OpenPGP card no. D2760001240102010006064764950000 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>
Then enter the information to customize your key:
gpg/card> name Cardholder's surname: Wilson Cardholder's given name: Eleven gpg/card> lang Language preferences: fr gpg/card> login Login data (account name): wilson.eleven@labs.com gpg/card> sex Sex ((M)ale, (F)emale or space): m gpg/card> quit
The key is now configured. We can export the private keys of the subkeys in the smart card.
The goal is to move the secret keys of the subkeys into the Yubikey. In order to do so, we will
select each subkey one by one with the key n
command and move it in the card with keytocard
.
In the end, there will be no more secrets in the gpg keychain.
Let's edit the key.
wilson@spaceship:~$ gpg2 --expert --edit-key 1A8132B1 gpg (GnuPG) 2.1.11; Copyright (C) 2016 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 rsa4096/1A8132B1 created: 2017-10-05 expires: 2018-10-05 usage: C trust: ultimate validity: ultimate ssb rsa4096/B73A9C79 created: 2017-10-05 expires: 2018-10-05 usage: E ssb rsa4096/9CC8B2FB created: 2017-10-05 expires: 2018-10-05 usage: S ssb rsa4096/8047B454 created: 2017-10-05 expires: 2018-10-05 usage: A [ultimate] (1). Wilson Eleven <wilson.eleven@labs.com> gpg>
Let's export the encryption key to B73A9C79
.
gpg> key 1 pub rsa4096/1A8132B1 created: 2017-10-05 expires: 2018-10-05 usage: C trust: ultimate validity: ultimate ssb* rsa4096/B73A9C79 created: 2017-10-05 expires: 2018-10-05 usage: E ssb rsa4096/9CC8B2FB created: 2017-10-05 expires: 2018-10-05 usage: S ssb rsa4096/8047B454 created: 2017-10-05 expires: 2018-10-05 usage: A [ultimate] (1). Wilson Eleven <wilson.eleven@labs.com>
The small asterisk in front of the key's fingerprint indicates that it's selected.
Enter keytocard
to export it to the Yubikey. Then type 2
which is the only choice. The Yubikey can store the 3 types
subkeys.
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
pub rsa4096/1A8132B1
created: 2017-10-05 expires: 2018-10-05 usage: C
trust: ultimate validity: ultimate
ssb* rsa4096/B73A9C79
created: 2017-10-05 expires: 2018-10-05 usage: E
card-no: 0006 06476495
ssb rsa4096/9CC8B2FB
created: 2017-10-05 expires: 2018-10-05 usage: S
ssb rsa4096/8047B454
created: 2017-10-05 expires: 2018-10-05 usage: A
[ultimate] (1). Wilson Eleven <wilson.eleven@labs.com>
gpg will ask you for the password of the secret encryption key and then the admin pin code of the Yubikey key. Once the Yubikey admin pin code entered, the secret encryption key is in the Yubikey. We can check it right after moving the other two keys.
Let's select the signature key. Deselect the first key and select the second.
gpg> key 1 pub rsa4096/1A8132B1 created: 2017-10-05 expires: 2018-10-05 usage: C trust: ultimate validity: ultimate ssb rsa4096/B73A9C79 created: 2017-10-05 expires: 2018-10-05 usage: E card-no: 0006 06476495 ssb rsa4096/9CC8B2FB created: 2017-10-05 expires: 2018-10-05 usage: S ssb rsa4096/8047B454 created: 2017-10-05 expires: 2018-10-05 usage: A [ultimate] (1). Wilson Eleven <wilson.eleven@labs.com> gpg> key 2 pub rsa4096/1A8132B1 created: 2017-10-05 expires: 2018-10-05 usage: C trust: ultimate validity: ultimate ssb rsa4096/B73A9C79 created: 2017-10-05 expires: 2018-10-05 usage: E card-no: 0006 06476495 ssb* rsa4096/9CC8B2FB created: 2017-10-05 expires: 2018-10-05 usage: S ssb rsa4096/8047B454 created: 2017-10-05 expires: 2018-10-05 usage: A [ultimate] (1). Wilson Eleven <wilson.eleven@labs.com> gpg>
The second key is well selected because there is the small asterisk in front of the key 9CC8B2FB
.
Repeat the operation with keytocard
command and select 1
because it's a key signature.
gpg> keytocard
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
pub rsa4096/1A8132B1
created: 2017-10-05 expires: 2018-10-05 usage: C
trust: ultimate validity: ultimate
ssb rsa4096/B73A9C79
created: 2017-10-05 expires: 2018-10-05 usage: E
card-no: 0006 06476495
ssb* rsa4096/9CC8B2FB
created: 2017-10-05 expires: 2018-10-05 usage: S
ssb rsa4096/8047B454
created: 2017-10-05 expires: 2018-10-05 usage: A
[ultimate] (1). Wilson Eleven <wilson.eleven@labs.com>
gpg>
It's ok for the second key. Repeat with the third.
gpg> key 2
pub rsa4096/1A8132B1
created: 2017-10-05 expires: 2018-10-05 usage: C
trust: ultimate validity: ultimate
ssb rsa4096/B73A9C79
created: 2017-10-05 expires: 2018-10-05 usage: E
card-no: 0006 06476495
ssb rsa4096/9CC8B2FB
created: 2017-10-05 expires: 2018-10-05 usage: S
ssb rsa4096/8047B454
created: 2017-10-05 expires: 2018-10-05 usage: A
[ultimate] (1). Wilson Eleven <wilson.eleven@labs.com>
gpg> key 3
pub rsa4096/1A8132B1
created: 2017-10-05 expires: 2018-10-05 usage: C
trust: ultimate validity: ultimate
ssb rsa4096/B73A9C79
created: 2017-10-05 expires: 2018-10-05 usage: E
card-no: 0006 06476495
ssb rsa4096/9CC8B2FB
created: 2017-10-05 expires: 2018-10-05 usage: S
ssb* rsa4096/8047B454
created: 2017-10-05 expires: 2018-10-05 usage: A
[ultimate] (1). Wilson Eleven <wilson.eleven@labs.com>
gpg> keytocard
Please select where to store the key:
(3) Authentication key
Your selection? 3
pub rsa4096/1A8132B1
created: 2017-10-05 expires: 2018-10-05 usage: C
trust: ultimate validity: ultimate
ssb rsa4096/B73A9C79
created: 2017-10-05 expires: 2018-10-05 usage: E
card-no: 0006 06476495
ssb rsa4096/9CC8B2FB
created: 2017-10-05 expires: 2018-10-05 usage: S
ssb* rsa4096/8047B454
created: 2017-10-05 expires: 2018-10-05 usage: A
[ultimate] (1). Wilson Eleven <wilson.eleven@labs.com>
gpg>
We are done. Type save
and quit
.
Let's check that we do not have any secret keys in our gpg keychain anymore.
wilson@spaceship:~$ gpg2 --list-secret-keys /home/wilson/.gnupg/pubring.gpg -------------------------------- sec# rsa4096/1A8132B1 2017-10-05 [C] [expires: 2018-10-05] uid [ultimate] Wilson Eleven <wilson.eleven@labs.com> ssb> rsa4096/B73A9C79 2017-10-05 [E] [expires: 2018-10-05] ssb> rsa4096/9CC8B2FB 2017-10-05 [S] [expires: 2018-10-05] ssb> rsa4096/8047B454 2017-10-05 [A] [expires: 2018-10-05]
The chevron >
before ssb
indicates that the secret key does not exist for this key. It's a stub.
Let's check that these secret keys are in the Yubikey.
wilson@spaceship:~$ gpg2 --card-status
Reader ...........: 1050:0407:X:0
Application ID ...: D2760001240102010006064764950000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 06476495
Name of cardholder: Eleven Wilson
Language prefs ...: fr
Sex ..............: male
URL of public key : [not set]
Login data .......: wilson.eleven@labs.com
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: 49B7 73DB 292F 8A66 C254 AC97 69FE 9865 9CC8 B2FB
created ....: 2017-10-05 11:39:18
Encryption key....: 88CD 3F3C BA60 1AFD D0A6 22E9 FE2B A21E B73A 9C79
created ....: 2017-10-05 11:36:19
Authentication key: 0E2F 255E DE28 F044 474D E571 F000 F81C 8047 B454
created ....: 2017-10-05 11:43:21
General key info..: sub rsa4096/9CC8B2FB 2017-10-05 Wilson Eleven <wilson.eleven@labs.com>
sec# rsa4096/1A8132B1 created: 2017-10-05 expires: 2018-10-05
ssb> rsa4096/B73A9C79 created: 2017-10-05 expires: 2018-10-05
card-no: 0006 06476495
ssb> rsa4096/9CC8B2FB created: 2017-10-05 expires: 2018-10-05
card-no: 0006 06476495
ssb> rsa4096/8047B454 created: 2017-10-05 expires: 2018-10-05
card-no: 0006 06476495
We find the personal information in the first part. Then there is the information on the keys stored in the Yubikey.
We see that there is the chevron >
before ssb
. As seen above, this indicates the absence of the secret key in the
keychain. Just below, there is an extra line that tells gpg where to find the secret key.
Here we have the serial number of the Yubikey card-no: 0006 06476495
. This serial number is also printed on the key physically.
If you have multiple Yubikeys, it will be easy to find the one you are looking for.
Through these first two articles, we covered the creation of an OpenPGP key and the export of secrets on a smart card. The use of a smart card provides additional protection against the theft of secret keys. It will not be enough to hack the computer to steal them, but it will be necessary to physically steal the key and the associated PIN code to use the secret keys. Moreover, as seen in the introduction, the secret key cannot be extracted. Our key is well protected, except against the human factor which remains the only threat.
In addition, you can distribute your public key on a key server and other services (GitHub, Kraken, keybase.io). This allows you to receive encrypted messages, and sign your commits on GitHub (example on this commit 31dd621).
In a future article, we will set up a backup strategy to cover for the potential loss of secret keys. An error can quickly happen, like erasing your computer following a ransomware.
This tutorial uses a Yubikey for storing secrets. Yubikey is the most popular key in the general public, especially for the second authentication factor feature. There are other keys that support OpenPGP such as NitroKey. Unlike the Yubikey, the NitroKey is open-source. Security with closed and proprietary hardware is not a viable solution in the long term. It's also contradictory to the OpenPGP spirit, that aims to be open. However, I chose the Yubikey for its ease of implementation and its ability to do double authentication.
Author(s)
Thierry T.
Super Data Boy
You wanna know more about something in particular?
Let's plan a meeting!
Our experts answer all your questions.
Contact usDiscover other content about the same topic
Guide to create the almost perfect OpenPGP keys
Today, I would like to share with you a feature often requested in an application: uploading a file.
Hello everyone! Today I would like to speak about a subject too little discussed in php: the exceptions. An exception is an alert issued when the code is executed, to indicate that something has not happened as expected. It can be a bad connection identifier to the database, or an operation on a file that is not allowed, or a division by zero for example.