# GPG

- [GPG](#gpg)
  - [Searching for GPG Keys](#searching-for-gpg-keys)
  - [Importing GPG Keys](#importing-gpg-keys)
  - [Generate GPG Keys](#generate-gpg-keys)
  - [Change Key Password](#change-key-password)
  - [Renewing GPG Keys](#renewing-gpg-keys)
  - [Export GPG Keys](#export-gpg-keys)
  - [GPG Key Servers](#gpg-key-servers)
  - [Delete GPG Keys](#delete-gpg-keys)
  - [Using GPG keys](#using-gpg-keys)
    - [Signing Files](#signing-files)
    - [Encrypting Files](#encrypting-files)
  - [Yubikey](#yubikey)
  - [Linux Apps](#linux-apps)
    - [Evolution Email](#evolution-email)
  - [Android Apps](#android-apps)
    - [OpenKeychain](#openkeychain)
    - [Fair Email](#fair-email)
  - [Troubleshooting](#troubleshooting)

## Searching for GPG Keys

I publish all my keys to <https://keys.openpgp.org>

```bash
# Search for an arbitrary user's key
gpg --auto-key-locate hkps://keys.openpgp.org --locate-keys <email>
```

## Importing GPG Keys

```bash
# First, locate a key
gpg --auto-key-locate hkps://keys.openpgp.org --locate-keys git@ducoterra.net

# Or import a key file
gpg --import keys/git_ducoterra_net.pub

# Sign the key with your own if you trust it
gpg -u 7FC1B29700114F4FC589E7065FDDCFA544D77B8C --sign-key git@ducoterra.net

# Then set the trust of the key
# full == I trust other keys signed by this key
# undefined == I'm choosing to defer to later
# never == I don't trust this key
gpg --quick-set-ownertrust git@ducoterra.net full
```

## Generate GPG Keys

```bash
# Make sure you have pinentry installed
dnf install pinentry

# Generate the key. The defaults should be good enough.
gpg --full-generate-key

# Verify your key was created
gpg --list-secret-keys

# Edit a key in your keyring
gpg --edit-key <id>
```

## Change Key Password

```bash
# You can see all the --edit-key options with `man gpg` and search for '--edit-key'
# You can also type "?" to see help
gpg --edit-key 7FC1B29700114F4FC589E7065FDDCFA544D77B8C

> passwd

> quit
```

## Renewing GPG Keys

You should set an expiration for your keys. You can extend that expiration (or
set it on existing keys) with:

```bash
# Note 2y == "expire 2 years from now"
# You can also set '0' for no expiration or use 'd' days and 'w' for weeks
gpg --quick-set-expire <key id> 2y

# Don't forget to republish your keys with new expirations
gpg --keyserver https://keys.openpgp.org --send-keys <key id>
```

## Export GPG Keys

```bash
# Export your public key in ascii format
gpg -o keys/git-ducoterra-net.gpg --export -a 'git@ducoterra.net'

# Export your private key (careful with this one)
gpg -o git-ducoterra-net.key --export-secret-keys -a 'git@ducoterra.net'
```

## GPG Key Servers

Edit `~/.gnupg/gpg.conf` and add `keyserver hkps://keys.openpgp.org`

```bash
# Sync keys with keyserver
gpg --refresh-keys

# Search for a user's key
gpg --auto-key-locate hkps://keys.openpgp.org --locate-keys git@ducoterra.net

# Export your public key
gpg --export -a 'git@ducoterra.net' > keys/git_ducoterra_net.pub

# Inspect a public key with
gpg --show-key keys/git_ducoterra_net.pub

# Upload a key to a keyserver
# NOTE: if you upload your key to keys.openpgp.org with this command, the email
# won't be searchable. You'll need to Use the upload page
# (https://keys.openpgp.org/upload) and upload the key file generated above
# instaed. You'll need to verify your email after upload for it to be searchable.
gpg --keyserver https://keys.openpgp.org --send-keys <key id>
```

## Delete GPG Keys

```bash
# Delete a public key
gpg --delete-keys <email>

# Delete a secret key
# Note, you'll also need to delete the public key after this command
gpg --delete-secret-keys <email>
```

## Using GPG keys

### Signing Files

```bash
# -s --sign
# -a --armor
# -u --local-user
# -e --encrypt
# -b --detach-sign
# -o --output

# Sign a file and compress it. Output will be binary
gpg -u 7FC1B29700114F4FC589E7065FDDCFA544D77B8C -o README.sig -s README.md

# Decompress and verify the signed file
gpg --output README.md --decrypt README.sig

# Sign a file without compressing it. Useful for serving/sending signed documents without requiring decompression
gpg -u 7FC1B29700114F4FC589E7065FDDCFA544D77B8C --clearsign -s -a README.md

# Verify the document (ignore the WARNING about detached signature)
gpg --verify README.md.asc

# Create a detached signature. The most practical option since you don't need to modify the original file.
gpg -u 7FC1B29700114F4FC589E7065FDDCFA544D77B8C -o README.md.sig -b README.md

# Verify the detached signature
gpg --verify README.md.sig README.md
```

### Encrypting Files

```bash
# -s --sign
# -a --armor
# -u --local-user
# -e --encrypt

# Encrypt a file with someone's public key
gpg -o README.md.gpg -e --recipient git@ducoterra.net README.md

# Decrypt the file if you have the private key
gpg -o README.md --decrypt README.md.gpg

# Encrypt with a password
gpg -o README.md.gpg --symmetric README.md

# Decrypt with a password
gpg --decrypt README.md.gpg
```

## Yubikey

See [Yubikey Notes](/active/device_yubikey/yubikey.md#gpg)

## Linux Apps

### Evolution Email

1. Edit -> Preferences -> Double click the account with a GPG key -> Security ->
OpenPGP Key ID
2. Always sign outgoing messages
3. Advanced Options -> Always trust keys in my keyring when encrypting

## Android Apps

### OpenKeychain

### Fair Email

## Troubleshooting

"error receiving key from agent: No such file or directory - skipped"

"error obtaining lock... process is in use by..."

In general, the easiest way to fix gpg problems is by killing and restarting the agent.

```bash
gpgconf --kill gpg-agent
gpgconf --reload gpg-agent
```