# GNU Privacy Guard (gpg)

## TL;DR

Useful commands from this page are below.

{% tabs %}
{% tab title="Generate" %}

```bash
gpg --gen-key
```

{% endtab %}

{% tab title="Revoke" %}

```bash
# revocation certificates can be issued if
# the private key is lost or compromised
gpg --output your-new-certificate-name.asc --gen-revoke your-key-id
```

{% endtab %}

{% tab title="List" %}

```bash
# list keys. helpful for finding the key id
gpg --list-keys
```

{% endtab %}

{% tab title="Export" %}

```
# print key to the terminal
gpg --armor --export your-email@your-domain.com your-key-id
```

{% endtab %}

{% tab title="Import" %}

```bash
# add an existing gpg key to profile
gpg --import $HOME/.gnupg/file-name.gpg

# sign the imported key
# ONLY IF YOU VERIFY THE FINGERPRINT!!!
gpg --edit-key someone-you-trust@their-domain.com
```

{% endtab %}

{% tab title="Encryption" %}

```bash
# encrypt file "your-file" (include file extension)
gpg --output your-file.gpg --encrypt \ # Set output file
    --recipient recipient-identity@domain.com \ 
    your-file # Source file to encrypt

# decrypt
gpg --output decrypted-file \ # Set output file
    --decrypt encrypted-file.gpg # Set input file (encrypted)
```

{% endtab %}
{% endtabs %}

## Overview

`GPG` (technically gpg2) is the [OpenPGP](https://www.openpgp.org/) part of the GNU Privacy Guard (GnuPG). It ships with your EC2 instance and offers **digital encryption and signing services.** It also can be used for secure shell applications ([GitHub supports GPG keys for SSH](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-new-gpg-key-to-your-github-account)).

Check out this[ great, simple guide for using GPG](https://www.gnupg.org/gph/en/manual/c14.html)

{% hint style="info" %}
Technically, the pre-installed package is\*\*`gpg2`\*\*, which is targeted for desktop use whereas the original **`gpg`** package is for server and embedded platforms. Your ec2 instance will interpret both **`gpg`** and **`gpg2`** commands as **`gpg2`**. This documentation will use the form **`gpg`** for simplicity.
{% endhint %}

## Tamper Resistant Digital Signatures

Digital signature certifies and timestamps a document. Any changes to that file, however slight, will be unable to pass the verification process.

{% hint style="info" %}
Creating and verifying signatures uses the public/private keypair from the **SSH** and **PKI** discussion; <mark style="color:orange;">**however, the operation is different from encryption and decryption.**</mark>
{% endhint %}

### Getting Started

Go ahead and create a new primary key pair so you can get started with **gpg.**

```bash
# input
gpg --gen-key

# output
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)
Your selection? 2 # 2 generates DSA for signing and Elgamal for encrypting
SA keys may be between 1024 and 3072 bits long.
What keysize do you want? (2048) 2048 # default is 2048
Requested keysize is 2048 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) # zero means no expiration
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

# enter your own information when you get to this screen
Real name: Kenneth Shultz
Email address: kshultz@permitzip.com
Comment: Gadget Engineering Director
You selected this USER-ID:
    "Kenneth Shultz (Gadget Engineering Director) <kshultz@permitzip.com>"
...
...
...
```

You will be prompted to create a passphrase for your key pair; proceed to do so, preferably using a memorable phrase with a length of several words.

**Take note of your new Key ID in the output (Line 3 below):**

```bash
# output
gpg: /home/ec2-user/.gnupg/trustdb.gpg: trustdb created
gpg: key 9FCE5492 marked as ultimately trusted #Key ID = 9FCE5492
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048D/9FCE5492 2022-06-09
Key fingerprint = CD37 7CB1 4E47 42DC D0C2  E0F1 12C5 ED0C 224F 4A80
uid   Kenneth Shultz (Gadget Engineering Director) <kshultz@permitzip.com>
sub   2048g/D436E7FC 2022-06-09

%
```

### Generate Revocation Certificate

With the new key pair created, immediately generate a revocation certificate for the primary public key.

* revocation certificates may be published to notify others that the public key has expired (perhaps due to a lost key, etc)
* can be used to verify signatures made in the past
* cannot be used to encrypt future messages
* does not impact the ability to decrypt past messages (if you still have the private key)

Create a revocation certificate using:

```bash
# input
gpg --output $HOME/.gnupg/your-new-certificate-name.asc --gen-revoke your-key-id # example key-id: 9FCE5492      

# output
sec  2048D/9FCE5492 2022-06-08 Kenneth Shultz (Gadget Engineering Director) <kshultz@permitzip.com>

Create a revocation certificate for this key? (y/N) y #confirm yes
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 0 
Enter an optional description; end it with an empty line:
>   #No description necessary; could enter something like 
    # "safety revocation certificate"
Reason for revocation: No reason specified
(No description given)
Is this okay? (y/N) y

You need a passphrase to unlock the secret key for
user: "Kenneth Shultz (Gadget Engineering Director) <kshultz@permitzip.com>"
# Use same passphrase from key creation process
2048-bit DSA key, ID 9FCE5492, created 2022-06-08

ASCII armored output forced.
Revocation certificate created.
...
...
```

Your revocation certificate has been stored in `$HOME/.gnupg/` as `your-new-certificate-name.asc` (See line 2 above). Check your key ring out now:

```bash
# input
gpg --list-keys

# output
/home/ec2-user/.gnupg/pubring.gpg
---------------------------------
pub   2048D/9FCE5492 2022-06-08
uid                  Kenneth Shultz (Gadget Engineering Director) <kshultz@permitzip.com>
sub   2048g/586776A7 2022-06-08
```

### Export a Public Key

You will need to share your key so that others may verify your signatures. Use the command below, but replace the email and key ID (*9FCE5492*) with your information:

```
# input
gpg --armor --export your-username@your-domain.com your-key-id
```

Here is an example output for Kenny Shultz, using <kshultz@permitzip.com> and key ID 9FCE5492:

```
# output
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)

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
G27bPWIzSw==
=z96n
-----END PGP PUBLIC KEY BLOCK-----
```

Lines 2 through 41 above (bounded header and footer included) can now be copied to the clipboard in order to share public key information anywhere.

### Add Another User's Public Key and Sign

You can add another user's public key to your keyring.

Copy and paste [**Kenny's**](https://permitzip.gitbook.io/dev-bible/getting-started/meet-the-team#kenny-shultz) public key from above (include the bounded header and footer).

Name it **`kenny.gpg`** and save it to **`$HOME/.gnupg`** then import the key using:

```
gpg --import $HOME/.gnupg/kenny.gpg
```

In order to certify the key on your system, you now must sign it:

```shell
# input
gpg --edit-key kshultz@permitzip.com

# output   
pub  2048D/9FCE5492  created: 2022-06-08  expires: never       usage: SC  
                     trust: unknown       validity: unknown
sub  2048g/586776A7  created: 2022-06-08  expires: never       usage: E   
[ unknown] (1). Kenneth Shultz (Gadget Engineering Director) <kshultz@permitzip.com>
```

A gpg shell has been spawned (`gpg>`); proceed to enter the following `fpr` and `sign` commands. **Before using your passphrase to complete the signing process, verify that the fingerprint (Line 9 below) matches exactly to:**

`4104 CFE0 F9A4 8B60 5253 A6BF ACAD E367 9FCE 5492`

```bash
# input
gpg> fpr

# output
pub   4096R/58360418 2015-09-24 Amazon Inspector <inspector@amazon.com>
  Primary key fingerprint: DDA0 D4C5 10AE 3C20 6F46  6DC0 2474 0960 5836 0418

# input
gpg> sign

# output
pub  2048D/9FCE5492  created: 2022-06-08  expires: never       usage: SC  
                     trust: unknown       validity: unknown
 Primary key fingerprint: 4104 CFE0 F9A4 8B60 5253  A6BF ACAD E367 9FCE 5492

     Kenneth Shultz (Gadget Engineering Director) <kshultz@permitzip.com>

Are you sure that you want to sign this key with your
key "Your Name (Your Key Description) <your-username@your-domain.com>" (your-keyID)

Really sign? (y/N) y
...
```

**Always verify fingerprints before signing and authorizing keys on your system.**

You can now use a force quit (ctrl+C) to exit the gpg terminal.

### Encrypting and Decrypting

You can use someone's public key to encrypt a message.

The message can only be decrypted with the recipient's private key (the key pair to the public key)

Try creating a file to encrypt - we'll create and use a message.txt file:

```
echo "here's a decrypted message" >> message.txt
```

Try encrypting with my or your own public key:

```shell
gpg --output message.txt.gpg --encrypt --recipient kshultz@permitzip.com message.txt
```

Here we pass <kshultz@permitzip.com> as the recipient to encrypt the message using Kenny's key. We create and define `message.txt.gpg` as the output (encrypted file).

**You will never be able to decrypt this file without Kenny's private key.**

[**Kenny**](https://permitzip.gitbook.io/dev-bible/getting-started/meet-the-team#kenny-shultz) could now decrypt this message **using his private key** and resolve it to `message.txt` with the command:

```
gpg --output message.txt --decrypt message.txt.gpg
```

If you'd like to try decrypting a file yourself, start this section over using your own public key to encrypt the file in place of Kenny's!
