Browse Source

draft: pgp post

restructure
Garrit Franke 3 years ago
parent
commit
75794b728b
Signed by: garrit
GPG Key ID: 65586C4DDA55EA2C
  1. 169
      content/posts/_2021-04-07-code-signing-should-be-the-norm.md
  2. BIN
      public/assets/signed_commit.png

169
content/posts/_2021-04-07-code-signing-should-be-the-norm.md

@ -0,0 +1,169 @@
---
title: Code signing should be the norm.
date: "2021-04-07"
---
In the past week, I've been experimenting with PGP, or GPG in particular. In a nutshell, PGP is an encryption standard with a wide range of use cases.
# The Why
For quite some time, I didn't see the point of keeping a PGP keypair. It seemed like a burden to securely keep track of the key(s). Once you loose it, you will loose the trust of others. But after doing some research on the topic, I found that it's not actually that much of a hassle, while giving you many benefits.
The most obvious benefit is encrypting and decrypting messages and files. If you upload your public key, I can encrypt our private conversations. Nobody will be able to read what we're chatting about. If you fear that cloud providers will read through your documents, you can also go ahead and encrypt all of your data with your keypair.
But PGP is not just about encryption. A keypair also gives you a proof of identity. If I see that a piece of work is signed by you, I can be certain that you and only you have worked on this.
Take Git commits for example. All it takes is a `git config user.email "elon@spacex.com"` and I can publish code under a different identity. But if everyone on the team signed their work, they will quickly see that a commit is missing its signature, because I'm simply not able to sign my work with Elon Musk's keypair. Only if they see a badge like this, they will know that they can trust it.
![A signed commit](/assets/signed_commit.png)
Your keypair can also come in handy as a SSH key. Before I knew about PGP, I always had to install one key per machine I was working on. With PGP, you only have a single identity, and therefore you only have to install one key on your servers.
# The How
Let's first go over the process of setting up a keypair. For this, we will need the `gpg` command installed on our system. Usually, this is just a `<package manager> install gpg` away. Then, we will have to generate a keypair. The quickest way to get one is to use `gpg --gen-key`, but that will make some quirky assumptions about how you want to use your key.
In PGP, there is this concept of a __keyring__. A keyring has one master key and many subkeys. It is generally a good idea to have one fat master key that never expires and many small subkeys that last about a year or two. The benefit of structuring your keys like this is that you will always have your trusted keychain, and in case something goes south, E.g. your key gets compromised, you can replace that subkey and keep your identity.
With that in mind, let's create our master key. Run `gpg --full-gen-key` and follow the instructions. You probably want to use the `RSA and RSA (default)` option, and a key that is 4096 bits long (remember, this is the fat master key that never expires, so it must be secure). The comment can be left blank, unless you know what you are doing with that field. Enter a strong passphrase! If your private key were to get compromised, this passphrase is your last line of defense. Make it long, hard to crack but still rememberable. If everything went well, your key should be generated. Here's the full example output:
```
root@c6acc9eb4fd1:/# gpg --full-gen-key
gpg (GnuPG) 2.2.19; Copyright (C) 2019 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.
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: Foo
Name must be at least 5 characters long
Real name: Foo Bar
Email address: foo@bar.com
Comment:
You selected this USER-ID:
"Foo Bar <foo@bar.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key C8E4854970B7A1A3 marked as ultimately trusted
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/4E83F95221E92EDB933F155AC8E4854970B7A1A3.rev'
public and secret key created and signed.
pub rsa4096 2021-04-07 [SC]
4E83F95221E92EDB933F155AC8E4854970B7A1A3
uid Foo Bar <foo@bar.com>
sub rsa4096 2021-04-07 [E]
```
You could stop here and use this key, but let's instead create some subkeys under that key, to make our lives a bit easier. Take the fingerprint of the key (that large number in the output) and run `gpg --edit-key --expert <your fingerprint>`. Run `addkey` three times to add these three keys:
## Signing key
This key will be used to sign your work (git commits, tags, etc.).
```
gpg> addkey
```
1. Choose option "RSA (set your own capabilities)", which is currently number 8.
1. Toggle E (Encryption) so the "Current allowed actions" only lists Sign and confirm with Q.
1. Choose the keysize 2048 (or whatever you prefer).
1. Choose the key expire date 1y (or whatever you prefer).
1. Confirm twice, then enter your passphrase.
## Encryption key
This key will be used to encrypt and decrypt messages.
```
gpg> addkey
```
1. Choose option "RSA (set your own capabilities)", which is currently number 8.
1. Toggle S (Sign) so the "Current allowed actions" only lists Encryption and confirm with Q.
1. Choose the keysize 2048 (or whatever you prefer).
1. Choose the key expire date 1y (or whatever you prefer).
1. Confirm twice, then enter your passphrase.
## Authentication key
This key will be used for SSH authentication.
```
gpg> addkey
```
1. Choose option "RSA (set your own capabilities)", which is currently number 8.
1. Toggle S (Signing), E (Encryption) and A (Authentication) so the "Current allowed actions" only lists Authenticate and confirm with Q.
1. Choose the keysize 2048 (or whatever you prefer).
1. Choose the key expire date 1y (or whatever you prefer).
1. Confirm twice, then enter your passphrase.
Now you should have one key per use case: signing, encrypting and authentication, each with an expiration date:
```
sec rsa4096/C8E4854970B7A1A3
created: 2021-04-07 expires: never usage: SC
trust: ultimate validity: ultimate
ssb rsa4096/C5F71423813B40A0
created: 2021-04-07 expires: never usage: E
ssb rsa2048/52D4D1D19533D8A5
created: 2021-04-07 expires: 2022-04-07 usage: S
ssb rsa2048/072D841844E3F949
created: 2021-04-07 expires: 2022-04-07 usage: E
ssb rsa2048/42E4F6E376DD92F6
created: 2021-04-07 expires: 2022-04-07 usage: A
[ultimate] (1). Foo Bar <foo@bar.com>
```
Let's put them to use!
## Code Signing
To sign your code, you will have to tell git which key to use. Edit your global git options (`~/.gitconfig`) and add these fields:
```
[commit]
gpgsign = true
[tag]
gpgsign = true
[user]
name = Foo Bar
signingkey = 52D4D1D19533D8A5! # Mind the trailing exclamation mark!
email = foo@bar.com
```
Now, whenever you sign a commit, git will sign it with your private key.
## Encrypting messages
## SSH
This is post 016 of [#100DaysToOffload](https://100daystooffload.com/).

BIN
public/assets/signed_commit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Loading…
Cancel
Save