Update the code integrity guide for 2021

- Remove traces of gnupg-1.4, as everything is finally gnupg-2.x
- Switch to using ECC cryptography for the subkeys
- Stop calling the certification subkey the "master key" as it's a
  bad analogy and that terminology isn't used anywhere in GnuPG docs

Signed-off-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
This commit is contained in:
Konstantin Ryabitsev 2021-05-13 12:41:52 -04:00
parent f879c68248
commit bc0503d8bf
No known key found for this signature in database
GPG Key ID: B6C41CE35664996C
1 changed files with 155 additions and 240 deletions

View File

@ -1,6 +1,6 @@
# Protecting code integrity with PGP
Updated: 2018-01-22
Updated: 2021-05-13
*Status: CURRENT*
@ -23,35 +23,31 @@ Updated: 2018-01-22
- [Web of Trust (WOT) vs. Trust on First Use (TOFU)](#web-of-trust-wot-vs-trust-on-first-use-tofu)
- [Installing OpenPGP software](#installing-openpgp-software)
- [Installing GnuPG](#installing-gnupg)
- [GnuPG 1 vs. 2](#gnupg-1-vs-2)
- [Making sure you always use GnuPG v.2](#making-sure-you-always-use-gnupg-v2)
- [Generating and protecting your master PGP key](#generating-and-protecting-your-master-pgp-key)
- [Generating and protecting your certification key](#generating-and-protecting-your-certification-key)
- [Checklist](#checklist-1)
- [Considerations](#considerations-1)
- [Understanding the "Master" (Certify) key](#understanding-the-%22master%22-certify-key)
- [Before you create the master key](#before-you-create-the-master-key)
- [Understanding the certification key](#understanding-the-certification-key)
- [Before you create the certification key](#before-you-create-the-certification-key)
- [Primary identity](#primary-identity)
- [Passphrase](#passphrase)
- [Algorithm and key strength](#algorithm-and-key-strength)
- [Generate the master key](#generate-the-master-key)
- [Back up your master key](#back-up-your-master-key)
- [Generate the certification key](#generate-the-certification-key)
- [Back up your certification key](#back-up-your-certification-key)
- [Add relevant identities](#add-relevant-identities)
- [Pick the primary UID](#pick-the-primary-uid)
- [Generating PGP subkeys](#generating-pgp-subkeys)
- [Checklist](#checklist-2)
- [Considerations](#considerations-2)
- [Create the subkeys](#create-the-subkeys)
- [Upload your public keys to the keyserver](#upload-your-public-keys-to-the-keyserver)
- [Upload your public key to GitHub](#upload-your-public-key-to-github)
- [Set up a refresh cronjob](#set-up-a-refresh-cronjob)
- [Moving your master key to offline storage](#moving-your-master-key-to-offline-storage)
- [Upload your public key to GitHub](#upload-your-public-key-to-github)
- [Moving your certification key to offline storage](#moving-your-certification-key-to-offline-storage)
- [Checklist](#checklist-3)
- [Considerations](#considerations-3)
- [Back up your GnuPG directory](#back-up-your-gnupg-directory)
- [Prepare detachable encrypted storage](#prepare-detachable-encrypted-storage)
- [Back up your GnuPG directory](#back-up-your-gnupg-directory-1)
- [Remove the master key](#remove-the-master-key)
- [Removing your master key](#removing-your-master-key)
- [Remove the certification key](#remove-the-certification-key)
- [Removing your certification key](#removing-your-certification-key)
- [Remove the revocation certificate](#remove-the-revocation-certificate)
- [Move the subkeys to a hardware device](#move-the-subkeys-to-a-hardware-device)
- [Checklist](#checklist-4)
@ -65,7 +61,7 @@ Updated: 2018-01-22
- [Verifying that the keys were moved](#verifying-that-the-keys-were-moved)
- [Verifying that the smartcard is functioning](#verifying-that-the-smartcard-is-functioning)
- [Other common GnuPG operations](#other-common-gnupg-operations)
- [Mounting your master key offline storage](#mounting-your-master-key-offline-storage)
- [Mounting your offline storage](#mounting-your-offline-storage)
- [Updating your regular GnuPG working directory](#updating-your-regular-gnupg-working-directory)
- [Extending key expiration date](#extending-key-expiration-date)
- [Revoking identities](#revoking-identities)
@ -78,7 +74,6 @@ Updated: 2018-01-22
- [Hashing function](#hashing-function)
- [Annotated tags and tag signatures](#annotated-tags-and-tag-signatures)
- [Signed commits](#signed-commits)
- [Signed pushes](#signed-pushes)
- [Configure git to use your PGP key](#configure-git-to-use-your-pgp-key)
- [How to work with signed tags](#how-to-work-with-signed-tags)
- [How to verify signed tags](#how-to-verify-signed-tags)
@ -325,66 +320,39 @@ of the commands in the guide to work for you, unless you have a unix-like
environment set up. For all other platforms, you'll need to do your own
research to find the correct places to download and install GnuPG.
##### GnuPG 1 vs. 2
Both GnuPG v.1 and GnuPG v.2 implement the same standard, but they provide
incompatible libraries and command-line tools, so many distributions ship both
the legacy version 1 and the latest version 2. You need to make sure you are
always using GnuPG v.2.
First, run:
$ gpg --version | head -n1
If you see `gpg (GnuPG) 1.4.x`, then you are using GnuPG v.1. Try the `gpg2`
command:
$ gpg2 --version | head -n1
If you see `gpg (GnuPG) 2.x.x`, then you are good to go. This guide will
assume you have the version 2.2 of GnuPG (or later). If you are using version
2.0 of GnuPG, some of the commands in this guide will not work, and you should
consider installing the latest 2.2 version of GnuPG.
##### Making sure you always use GnuPG v.2
If you have both `gpg` and `gpg2` commands, you should make sure you are
always using GnuPG v2, not the legacy version. You can make sure of this by
setting the alias:
$ alias gpg=gpg2
You can put that in your `.bashrc` to make sure it's always loaded whenever
you use the gpg commands.
## Generating and protecting your master PGP key
## Generating and protecting your certification key
### Checklist
- [ ] Generate a 4096-bit RSA master key _(ESSENTIAL)_
- [ ] Back up the master key using paperkey _(ESSENTIAL)_
- [ ] Generate a 4096-bit RSA certification key _(ESSENTIAL)_
- [ ] Back up the certification key using paperkey _(ESSENTIAL)_
- [ ] Add all relevant identities _(ESSENTIAL)_
### Considerations
#### Understanding the "Master" (Certify) key
#### Understanding the certification key
In this and next section we'll talk about the "master key" and "subkeys". It
is important to understand the following:
In this and next section we'll talk about the certification key and subkeys.
The certification key is often called "the master key," but it is a poor
analogy, as it doesn't act in any way like a physical master key (in the sense
that it cannot decrypt content encrypted to any of the subkeys, as one
example). For this reason, we'll stick to calling it the "certification key."
1. There are no technical differences between the "master key" and "subkeys."
It is important to understand the following:
1. There are no technical differences between the certify key and any of the
subkeys
2. At creation time, we assign functional limitations to each key by
giving it specific capabilities.
3. A PGP key can have 4 capabilities.
3. A PGP key can have 4 capabilities:
- **[S]** key can be used for signing
- **[E]** key can be used for encryption
- **[A]** key can be used for authentication
- **[C]** key can be used for certifying other keys
4. A single key may have multiple capabilities.
The key carrying the **[C]** (certify) capability is considered the "master"
key because it is the only key that can be used to indicate relationship with
other keys. Only the **[C]** key can be used to:
The key carrying the **[C]** (certify) capability is used to indicate
relationship with other PGP keys. Only the **[C]** key can be used to:
- add or revoke other keys (subkeys) with S/E/A capabilities
- add, change or revoke identities (uids) associated with the key
@ -395,10 +363,10 @@ In the Free Software world, the **[C]** key is your digital identity. Once you
create that key, you should take extra care to protect it and prevent it from
falling into malicious hands.
#### Before you create the master key
#### Before you create the certify key
Before you create your master key you need to pick your primary identity and
your master passphrase.
Before you create your certify key you need to pick your primary identity and
your passphrase.
##### Primary identity
@ -428,23 +396,24 @@ to type and easy to remember.
##### Algorithm and key strength
Even though GnuPG has had support for Elliptic Curve crypto for a while now,
we'll be sticking to RSA keys, at least for a little while longer. While it is
possible to start using ED25519 keys right now, it is likely that you will
come across tools and hardware devices that will not be able to handle them
correctly.
GnuPG supports many algorithms, but we will only consider the below two:
You may also wonder why the master key is 4096-bit, if later in the guide we
state that 2048-bit keys should be good enough for the lifetime of RSA public
key cryptography. The reasons are mostly social and not technical: master keys
happen to be the most visible ones on the keychain, and some of the developers
you interact with will inevitably judge you negatively if your master key has
fewer bits than theirs.
- RSA for the certification key
- ECC (Elliptic Curve) for all other subkeys
#### Generate the master key
We use RSA for the certification key mainly for compatibility reasons -- there
is probably still some tooling that does not properly handle ECC keys, so
sticking with RSA for the certification key makes sense. We will use it only
very occasionally, so the slowness/size considerations are unimportant.
To generate your new master key, issue the following command, putting in the
right values instead of "Alice Engineer:"
All of the day-to-day work will be done using subkeys, so picking ECC makes
perfect sense there -- it will be faster and the resulting signatures will be
dramatically smaller.
#### Generate the certification key
To generate your new certification key, issue the following command, putting
in the right values instead of "Alice Engineer:"
$ gpg --quick-generate-key 'Alice Engineer <alice@example.org>' rsa4096 cert
@ -454,7 +423,7 @@ the command completes.
Review the output of the command, it will be something like this:
pub rsa4096 2017-12-06 [C] [expires: 2019-12-06]
pub rsa4096 2021-05-01 [C] [expires: 2023-05-01]
111122223333444455556666AAAABBBBCCCCDDDD
uid Alice Engineer <alice@example.org>
@ -472,7 +441,7 @@ At this point, I suggest you open a text editor, copy the fingerprint of your
new key and paste it there. You'll need to use it for the next few steps, so
having it close by will be handy.
#### Back up your master key
#### Back up your certification key
For disaster recovery purposes -- and especially if you intend to use the Web
of Trust and collect key signatures from other project developers -- you
@ -508,9 +477,9 @@ safe operation, but use your best paranoid judgement.
#### Add relevant identities
If you have multiple relevant email addresses (personal, work, open-source
project, etc), you should add them to your master key. You don't need to do
this for any addresses that you don't expect to use with PGP (e.g. probably
not your school alumni address).
project, etc), you should add them to your key. You don't need to do this for
any addresses that you don't expect to use with PGP (e.g. probably not your
school alumni address).
The command is (put the full key fingerprint instead of `[fpr]`):
@ -531,78 +500,58 @@ different from what you want, you should fix it back:
### Checklist
- [ ] Generate a 2048-bit Encryption subkey _(ESSENTIAL)_
- [ ] Generate a 2048-bit Signing subkey _(ESSENTIAL)_
- [ ] Generate a 2048-bit Authentication subkey _(NICE)_
- [ ] Upload your public keys to a PGP keyserver _(ESSENTIAL)_
- [ ] Set up a refresh cronjob _(ESSENTIAL)_
- [ ] Generate the Encryption subkey _(ESSENTIAL)_
- [ ] Generate the Signing subkey _(ESSENTIAL)_
- [ ] Generate the Authentication subkey _(NICE)_
- [ ] Upload your public keys to a PGP keyserver _(NICE)_
- [ ] Set up a refresh cronjob _(NICE)_
### Considerations
Now that we've created the master key, let's create the keys you'll actually
be using for day-to-day work. We create 2048-bit keys because a lot of
specialized hardware (we'll discuss this further) does not handle larger keys,
but also for pragmatic reasons. If we ever find ourselves in a world where
2048-bit RSA keys are not considered good enough, it will be because of
fundamental breakthroughs in computing or mathematics and therefore longer
4096-bit keys will not make much difference.
Now that we've created the certification key, let's create the keys you'll
actually be using for day-to-day work. Before we do this, we need to pick the
ECC algorithm flavor.
#### ED25519 or NIST?
We won't go into the reasons behind why ECC is split into two camps. All you
need to know is that many people consider ed25519 "more pure" due to the way
its underlying curve primitives were selected and NIST "less pure" because
that selection process was not as public or thorough.
Do you plan to use a hardware device like a Yubikey for storing your subkeys?
Then pick NIST (use "nistp256" instead of "cv25519" and "ed25519" below). If
you just plan to store your subkeys on your computer, then pick ED25519 (the
GnuPG default).
Since you can revoke subkeys and create new ones at any time, this is not a
life or death kind of decision. If in doubt, pick ed25519.
#### Create the subkeys
To create the subkeys, run:
$ gpg --quick-add-key [fpr] rsa2048 encr
$ gpg --quick-add-key [fpr] rsa2048 sign
$ gpg --quick-add-key [fpr] cv25519 encr
$ gpg --quick-add-key [fpr] ed25519 sign
You can also create the Authentication key, which will allow you to use your
PGP key for ssh purposes:
$ gpg --quick-add-key [fpr] rsa2048 auth
$ gpg --quick-add-key [fpr] ed25519 auth
You can review your key information using `gpg --list-key [fpr]`:
pub rsa4096 2017-12-06 [C] [expires: 2019-12-06]
pub rsa4096 2021-05-01 [C] [expires: 2023-05-01]
111122223333444455556666AAAABBBBCCCCDDDD
uid [ultimate] Alice Engineer <alice@example.org>
uid [ultimate] Alice Engineer <allie@example.net>
sub rsa2048 2017-12-06 [E]
sub rsa2048 2017-12-06 [S]
sub cv25519 2021-05-01 [E]
sub ed25519 2021-05-01 [S]
#### Upload your public keys to the keyserver
#### Upload your public key to GitHub
Your key creation is complete, so now you need to make it easier for others to
find it by uploading it to one of the public keyservers. (Do not do this step
if you're just messing around and aren't planning on actually using the key
you've created, as this just litters keyservers with useless data.)
$ gpg --send-key [fpr]
If this command does not succeed, you can try specifying the keyserver on a
port that is most likely to work:
$ gpg --keyserver hkp://pgp.mit.edu:80 --send-key [fpr]
Most keyservers communicate with each-other, so your key information will
eventually synchronize to all the others.
**NOTE ON PRIVACY:** Keyservers are completely public and therefore, by
design, leak potentially sensitive information about you, such as your full
name, nicknames, and personal or work email addresses. If you sign other
people's keys or someone signs yours, keyservers will additionally become
leakers of your social connections. Once such personal information makes it to
the keyservers, it becomes impossible to edit or delete. Even if you revoke a
signature or identity, that does not delete them from your key record, just
marks them as revoked -- making them stand out even more.
That said, if you participate in software development on a public project, all
of the above information is already public record, and therefore making it
additionally available via keyservers does not result in a net loss in
privacy.
##### Upload your public key to GitHub
If you use GitHub in your development (and who doesn't?), you should upload
your key following the instructions they have provided:
If you use GitHub in your development, you should upload your key following
the instructions they have provided:
- [Adding a PGP key to your GitHub account](https://help.github.com/articles/adding-a-new-gpg-key-to-your-github-account/)
@ -610,39 +559,33 @@ To generate the public key output suitable to paste in, just run:
$ gpg --export --armor [fpr]
#### Set up a refresh cronjob
#### Upload your public key to keys.openpgp.org
You will need to regularly refresh your keyring in order to get the latest
changes on other people's public keys. You can set up a cronjob to do that:
To make it easier for others to find your public key, you can upload it to the
keys.openpgp.org keyserver. Please follow the instructions provided here:
$ crontab -e
- [Upload to keys.openpgp.org](https://keys.openpgp.org/about/usage#gnupg-upload)
Add the following on a new line:
@daily /usr/bin/gpg2 --refresh >/dev/null 2>&1
**NOTE**: check the full path to your `gpg` or `gpg2` command and use the `gpg2`
command if regular `gpg` for you is the legacy GnuPG v.1.
## Moving your master key to offline storage
## Moving your cerification key to offline storage
### Checklist
- [ ] Prepare encrypted detachable storage _(ESSENTIAL)_
- [ ] Back up your GnuPG directory _(ESSENTIAL)_
- [ ] Remove the master key from your home directory _(NICE)_
- [ ] Remove the certification key from your home directory _(NICE)_
- [ ] Remove the revocation certificate from your home directory _(NICE)_
### Considerations
Why would you want to remove your master **[C]** key from your home directory?
This is generally done to prevent your master key from being stolen or
accidentally leaked. Private keys are tasty targets for malicious actors -- we
know this from several successful malware attacks that scanned users' home
Why would you want to remove your certification (**[C]**) key from your home
directory? This is generally done to prevent it from being stolen or
accidentally leaked. Private keys are tasty targets for malicious actors --
we know this from several successful malware attacks that scanned users' home
directories and uploaded any private key content found there.
It would be very damaging for any developer to have their PGP keys stolen --
in the Free Software world this is often tantamount to identity theft.
in the Free Software world this is basically equal to identity theft.
Removing private keys from your home directory helps protect you from such
events.
@ -662,7 +605,8 @@ for backup purposes. You will first need to encrypt them:
- [Apple instructions](https://support.apple.com/kb/PH25745)
- [Linux instructions](https://help.ubuntu.com/community/EncryptedFilesystemsOnRemovableStorage)
For the encryption passphrase, you can use the same one as on your master key.
For the encryption passphrase, you can use the same one as on your private
key.
#### Back up your GnuPG directory
@ -688,7 +632,7 @@ a random USB drive, and put in a safe place -- but not too far away, because
you'll need to use it every now and again for things like editing identities,
adding or revoking subkeys, or signing other people's keys.
#### Remove the master key
#### Remove the certification key
The files in our home directory are not as well protected as we like to think.
They can be leaked or stolen via many different means:
@ -702,32 +646,32 @@ They can be leaked or stolen via many different means:
Protecting your key with a good passphrase greatly helps reduce the risk of
any of the above, but passphrases can be discovered via keyloggers,
shoulder-surfing, or any number of other means. For this reason, the
recommended setup is to remove your master key from your home directory and
store it on offline storage.
recommended setup is to remove your certification key from your home directory
and store it on offline storage.
##### Removing your master key
##### Removing your certification key
Please see the previous section and make sure you have backed up your GnuPG
directory in its entirety. What we are about to do will render your key
useless if you do not have a usable backup!
First, identify the keygrip of your master key:
First, identify the "keygrip" of your certification key:
$ gpg --with-keygrip --list-key [fpr]
The output will be something like this:
pub rsa4096 2017-12-06 [C] [expires: 2019-12-06]
pub rsa4096 2021-05-01 [C] [expires: 2023-05-01]
111122223333444455556666AAAABBBBCCCCDDDD
Keygrip = AAAA999988887777666655554444333322221111
uid [ultimate] Alice Engineer <alice@example.org>
uid [ultimate] Alice Engineer <allie@example.net>
sub rsa2048 2017-12-06 [E]
sub cv25519 2021-05-01 [E]
Keygrip = BBBB999988887777666655554444333322221111
sub rsa2048 2017-12-06 [S]
sub ed25519 2021-05-01 [S]
Keygrip = CCCC999988887777666655554444333322221111
Find the keygrip entry that is beneath the `pub` line (right under the master
Find the keygrip entry that is beneath the `pub` line (right under the public
key fingerprint). This will correspond directly to a file in your home
`.gnupg` directory:
@ -738,34 +682,34 @@ key fingerprint). This will correspond directly to a file in your home
CCCC999988887777666655554444333322221111.key
All you have to do is simply remove the `.key` file that corresponds to the
master keygrip:
certification keygrip:
$ cd ~/.gnupg/private-keys-v1.d
$ rm AAAA999988887777666655554444333322221111.key
Now, if you issue the `--list-secret-keys` command, it will show that the
master key is missing (the `#` indicates it is not available):
**[C]** key is not present (indicated by the `#` character):
$ gpg --list-secret-keys
sec# rsa4096 2017-12-06 [C] [expires: 2019-12-06]
sec# rsa4096 2021-05-01 [C] [expires: 2023-05-01]
111122223333444455556666AAAABBBBCCCCDDDD
uid [ultimate] Alice Engineer <alice@example.org>
uid [ultimate] Alice Engineer <allie@example.net>
ssb rsa2048 2017-12-06 [E]
ssb rsa2048 2017-12-06 [S]
ssb cv25519 2021-05-01 [E]
ssb ed25519 2021-05-01 [S]
#### Remove the revocation certificate
Another file you should remove (but keep in backups) is the revocation
certificate that was automatically created with your master key. A revocation
certificate allows someone to permanently mark your key as revoked, meaning it
can no longer be used or trusted for any purpose. You would normally use it to
revoke a key that, for some reason, you can no longer control -- for example,
if you had lost the key passphrase.
certificate that was automatically created with your certification key. A
revocation certificate allows someone to permanently mark your key as revoked,
meaning it can no longer be used or trusted for any purpose. You would
normally use it to revoke a key that, for some reason, you can no longer
control -- for example, if you had lost the key passphrase.
Just as with the master key, if a revocation certificate leaks into malicious
hands, it can be used to destroy your developer digital identity, so it's
better to remove it from your home directory.
Just as with the certification key, if a revocation certificate leaks into
malicious hands, it can be used to destroy your developer digital identity, so
it's better to remove it from your home directory.
cd ~/.gnupg/openpgp-revocs.d
rm [fpr].rev
@ -781,7 +725,7 @@ better to remove it from your home directory.
### Considerations
Even though the master key is now safe from being leaked or stolen, the
Even though the certification key is now safe from being leaked or stolen, the
subkeys are still in your home directory. Anyone who manages to get their
hands on those will be able to decrypt your communication or fake your
signatures (if they know the passphrase). Furthermore, each time a GnuPG
@ -826,17 +770,18 @@ features on the internal chip. Here are a few recommendations:
- [Nitrokey Start](https://shop.nitrokey.com/shop/product/nitrokey-start-6):
Open hardware and Free Software: one of the cheapest options for GnuPG use,
but with fewest extra security features
but with fewest extra security features.
- [Nitrokey Pro](https://shop.nitrokey.com/shop/product/nitrokey-pro-3):
Similar to the Nitrokey Start, but is tamper-resistant and offers more
security features (but not U2F, see the Fido U2F section of the guide)
- [Yubikey 4](https://www.yubico.com/product/yubikey-4-series/): Proprietary
hardware and software, but cheaper than Nitrokey Pro and comes available
in the USB-C form that is more useful with newer laptops; also offers
additional security features such as U2F
security features (but not U2F, see the Fido U2F section of the guide); only
supports NIST ECC cryptography.
- [Yubikey](https://www.yubico.com/): Proprietary hardware and software, but
cheaper than Nitrokey Pro and comes available in the USB-C form that is more
useful with newer laptops; also offers additional security features such as
U2F; only supports NIST ECC cryptography.
Our recommendation is to pick a device that is capable of both smartcard
functionality and U2F, which, at the time of writing, means a Yubikey 4.
If you want to use ED25519 subkeys, then your only choice is a Nitrokey Start,
though once Nitrokey 3 Pro is available, it should also be considered.
#### Configuring your smartcard device
@ -894,12 +839,12 @@ the full 40-character fingerprint of your key.
Secret subkeys are available.
pub rsa4096/AAAABBBBCCCCDDDD
created: 2017-12-07 expires: 2019-12-07 usage: C
created: 2021-05-01 expires: 2023-05-01 usage: C
trust: ultimate validity: ultimate
ssb rsa2048/1111222233334444
created: 2017-12-07 expires: never usage: E
ssb rsa2048/5555666677778888
created: 2017-12-07 expires: never usage: S
ssb cv25519/1111222233334444
created: 2021-05-01 expires: never usage: E
ssb ed25519/5555666677778888
created: 2021-05-01 expires: never usage: S
[ultimate] (1). Alice Engineer <alice@example.org>
[ultimate] (2) Alice Engineer <allie@example.net>
@ -917,12 +862,12 @@ typing `key 1` (it's the first one in the listing, our **[E]** subkey):
The output should be subtly different:
pub rsa4096/AAAABBBBCCCCDDDD
created: 2017-12-07 expires: 2019-12-07 usage: C
created: 2021-05-01 expires: 2023-05-01 usage: C
trust: ultimate validity: ultimate
ssb* rsa2048/1111222233334444
created: 2017-12-07 expires: never usage: E
ssb rsa2048/5555666677778888
created: 2017-12-07 expires: never usage: S
ssb* cv25519/1111222233334444
created: 2021-05-01 expires: never usage: E
ssb ed25519/5555666677778888
created: 2021-05-01 expires: never usage: S
[ultimate] (1). Alice Engineer <alice@example.org>
[ultimate] (2) Alice Engineer <allie@example.net>
@ -974,12 +919,12 @@ If you perform `--list-secret-keys` now, you will see a subtle difference in
the output:
$ gpg --list-secret-keys
sec# rsa4096 2017-12-06 [C] [expires: 2019-12-06]
sec# rsa4096 2021-05-01 [C] [expires: 2023-05-01]
111122223333444455556666AAAABBBBCCCCDDDD
uid [ultimate] Alice Engineer <alice@example.org>
uid [ultimate] Alice Engineer <allie@example.net>
ssb> rsa2048 2017-12-06 [E]
ssb> rsa2048 2017-12-06 [S]
ssb> cv25519 2021-05-01 [E]
ssb> ed25519 2021-05-01 [S]
The `>` in the `ssb>` output indicates that the subkey is only available on
the smartcard. If you go back into your secret keys directory and look at the
@ -1013,10 +958,10 @@ your PGP key.
In all of the below commands, the `[fpr]` is your key fingerprint.
#### Mounting your master key offline storage
#### Mounting your offline storage
You will need your master key for any of the operations below, so you will
first need to mount your backup offline storage and tell GnuPG to use it.
You will need your certification key for any of the operations below, so you
will first need to mount your backup offline storage and tell GnuPG to use it.
First, find out where the media got mounted, e.g. by looking at the output of
the `mount` command. Then, locate the directory with the backup of your GnuPG
directory and tell GnuPG to use that as its home:
@ -1038,18 +983,18 @@ want to import these changes back into your regular working directory:
#### Extending key expiration date
The master key we created has the default expiration date of 2 years from the
date of creation. This is done both for security reasons and to make obsolete
keys eventually disappear from keyservers.
The certification key we created has the default expiration date of 2 years
from the date of creation. This is done both for security reasons and to make
obsolete keys eventually disappear from keyservers.
To extend the expiration on your key by a year from current date, just run:
$ gpg --quick-set-expire [fpr] 1y
You can also use a specific date if that is easier to remember (e.g. your
birthday, January 1st, or Canada Day):
birthday, January 1st, or Canada Day, 2030):
$ gpg --quick-set-expire [fpr] 2020-07-01
$ gpg --quick-set-expire [fpr] 2030-07-01
Remember to send the updated key back to keyservers:
@ -1080,8 +1025,7 @@ location, but what if someone had managed to trick you?
Or what happens if a backdoor is discovered in one of the projects you've
worked on, and the "Author" line in the commit says it was done by you, while
you're pretty sure you had [nothing to do with
it](https://github.com/jayphelps/git-blame-someone-else)?
you're pretty sure you had [nothing to do with it](https://github.com/jayphelps/git-blame-someone-else)?
To address both of these issues, Git introduced PGP integration. Signed tags
prove the repository integrity by assuring that its contents are exactly the
@ -1091,7 +1035,7 @@ having access to your PGP keys.
### Checklist
- [ ] Understand signed tags, commits, and pushes _(ESSENTIAL)_
- [ ] Understand signed tags, commits _(ESSENTIAL)_
- [ ] Configure git to use your key _(ESSENTIAL)_
- [ ] Learn how tag signing and verification works _(ESSENTIAL)_
- [ ] Configure git to always sign annotated tags _(NICE)_
@ -1102,8 +1046,7 @@ having access to your PGP keys.
### Considerations
Git implements multiple levels of integration with PGP, first starting with
signed tags, then introducing signed commits, and finally adding support for
signed pushes.
signed tags, and then introducing signed commits.
#### Understanding Git Hashes
@ -1182,24 +1125,6 @@ developer's tree at the time the signature was made. Tag signatures and commit
PGP signatures provide exact same security assurances about the repository and
its entire history.
#### Signed pushes
This is included here for completeness' sake, since this functionality needs
to be enabled on the server receiving the push before it does anything useful.
As we saw above, PGP-signing a git object gives verifiable information about
the developer's git tree, but not about their *intent* for that tree.
For example, you can be working on an experimental branch in your own git fork
trying out a promising cool feature, but after you submit your work for
review, someone finds a nasty bug in your code. Since your commits are
properly signed, someone can take the branch containing your nasty bug and
push it into master, introducing a vulnerability that was never intended to go
into production. Since the commit is properly signed with your key, everything
looks legitimate and your reputation is questioned when the bug is discovered.
Ability to require PGP-signatures during `git push` was added in order to
certify the *intent* of the commit, and not merely verify its contents.
#### Configure git to use your PGP key
If you only have one secret key in your keyring, then you don't really need to
@ -1210,11 +1135,6 @@ key should be used (`[fpr]` is the fingerprint of your key):
$ git config --global user.signingKey [fpr]
**NOTE**: If you have a distinct `gpg2` command, then you should tell git to
always use it instead of the legacy `gpg` from version 1:
$ git config --global gpg.program gpg2
#### How to work with signed tags
To create a signed tag, simply pass the `-s` switch to the tag command:
@ -1360,18 +1280,12 @@ smartcard, you can use it with ssh for adding 2-factor authentication for your
ssh sessions. You just need to tell your environment to use the correct socket
file for talking to the agent.
First, add the following to your `~/.gnupg/gpg-agent.conf`:
enable-ssh-support
Then, add this to your `.bashrc`:
All you need is add this to your `.bashrc`:
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
You will need to kill the existing `gpg-agent` process and start a new login
session for the changes to take effect:
Then start a new login session for the changes to take effect:
$ killall gpg-agent
$ bash
$ ssh-add -L
@ -1500,7 +1414,8 @@ By this point you have accomplished the following important tasks:
1. Created your developer identity and protected it using PGP cryptography.
2. Configured your environment so your identity is not easily stolen by moving
your master key offline and your subkeys to an external hardware device.
your certification key offline and your subkeys to an external hardware
device.
3. Configured your git environment to ensure that anyone using your project is
able to verify the integrity of the repository and its entire history.
4. Secured your online accounts using 2-factor authentication.