178 lines
6.3 KiB
Markdown
178 lines
6.3 KiB
Markdown
|
# GnuPG
|
||
|
Key files are a secure method for certifying credentials digitally. Everything
|
||
|
is stored in `~/.gnupg` and controlled through `gpg`. It's quite complicated...
|
||
|
See `tldr gpg` for encryption, [devhints](https://devhints.io/gnupg) for a
|
||
|
cheat sheet, the [Archwiki](https://wiki.archlinux.org/title/GnuPG) for a
|
||
|
technical explanation and the [Debian wiki](https://wiki.debian.org/Subkeys) for
|
||
|
a newbie-friendly one
|
||
|
|
||
|
Terminology:
|
||
|
|
||
|
* Public key - The one to share
|
||
|
* Private key - The one to not share
|
||
|
* Primary key - ??
|
||
|
* Subkey - ??
|
||
|
* Keygrip - The name of the key file
|
||
|
* Key ID - The last few (8-16) characters of a fingerprint
|
||
|
* Fingerprint - A unique identifier for a key
|
||
|
* Keyring - Your entire collection of public or private keys
|
||
|
* User ID - Email, part of name, Key ID, or Fingerprint of a key
|
||
|
|
||
|
Consider this example output:
|
||
|
```bash
|
||
|
$ gpg --list-secret-keys --with-subkey-fingerprint --with-keygrip --keyid-format=long
|
||
|
|
||
|
# ///--- Short for "secret key". It's "pub" for public keys
|
||
|
# vvv vvvvvvvvvvvvvvvv Key ID
|
||
|
> sec ed25519/ABCDEFG123456789 4040-04-04 [SC] [expires: 4040-04-04]
|
||
|
> DDEEDF222222222222222222ABCDEFG123456789
|
||
|
# ^^^^^^^^^^^^^^^^ Key ID also here
|
||
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fingerprint
|
||
|
> Keygrip = DDEBBA3482394AEE23432DEE32432BB2432432EE
|
||
|
# Key is ~/.gnupg/private-keys-v1.d/DDEBBA3482394AEE23432DEE32432BB2432432EE.key
|
||
|
> uid [ultimate] Emiliko Mirror <emiliko@mami2.moe>
|
||
|
# ///--- Short for "secret subkey". It's "sub" for public subkeys
|
||
|
# vvv vvvvvvvvvvvvvvvv Key ID
|
||
|
> ssb cv25519/987654321ABCDEED 4040-04-04 [E] [expires: 4040-04-04]
|
||
|
> 32423BDDAAAAAAAAAAAAAAAA987654321ABCDEED
|
||
|
# ^^^^^^^^^^^^^^^^ Key ID also here
|
||
|
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fingerprint from --with-subkey-fingerprint
|
||
|
> Keygrip = 2493ADDEDDDFEFEFE23432432FDEEFDD24324232
|
||
|
# Key is ~/.gnupg/private-keys-v1.d/2493ADDEDDDFEFEFE23432432FDEEFDD24324232.key
|
||
|
```
|
||
|
|
||
|
Providing the `--fingerprint` flag will alter the output slightly, tho it's the
|
||
|
same fingerprint, for example:
|
||
|
|
||
|
```bash
|
||
|
> sec ed25519/ABCDEFG123456789 4040-04-04 [SC] [expires: 4040-04-04]
|
||
|
> Key fingerprint = DDEE DF22 2222 2222 2222 2222 ABCD EFG1 2345 6789
|
||
|
# Key ID is now here ^^^^^^^^^^^^^^^^^^^
|
||
|
> Keygrip = DDEBBA3482394AEE23432DEE32432BB2432432EE
|
||
|
> uid [ultimate] Emiliko Mirror <emiliko@mami2.moe>
|
||
|
> ssb cv25519/987654321ABCDEED 4040-04-04 [E] [expires: 4040-04-04]
|
||
|
> Key fingerprint = 3242 3BDD AAAA AAAA AAAA AAAA 9876 5432 1ABC DEED
|
||
|
# Key ID is now here ^^^^^^^^^^^^^^^^^^^
|
||
|
> Keygrip = 2493ADDEDDDFEFEFE23432432FDEEFDD24324232
|
||
|
```
|
||
|
|
||
|
## Creating a new key
|
||
|
This closely follows the Archwiki, with an elliptic cipher
|
||
|
|
||
|
```
|
||
|
gpg --full-gen-key --expert
|
||
|
> (9) ECC and ECC
|
||
|
> (1) Curve 25519
|
||
|
> 1y # Optional, 1 year is recommended
|
||
|
> Your Name # This will be visible in the public key
|
||
|
> emiliko@mami2.moe # This is also visible in the public key
|
||
|
> No comment
|
||
|
> Put a password on the primary key
|
||
|
```
|
||
|
|
||
|
## Signing and verification
|
||
|
Git commits, binaries and really any file can be signed by a private key to
|
||
|
prove authenticity of the file. For github, you'll need to paste your public key
|
||
|
to your profile settings
|
||
|
|
||
|
```bash
|
||
|
gpg --list-secret-keys --keyid-format=long
|
||
|
gpg --armor --export <user-id> | wl-copy
|
||
|
```
|
||
|
|
||
|
Git commits aren't signed by default. Either explicitly sign at commit time,
|
||
|
with `git commit -S`, or add the following to your ~/.gitconfig. If the signing
|
||
|
key you specify is a subkey, add an ! mark at the end
|
||
|
|
||
|
```toml
|
||
|
[user]
|
||
|
name = Emiliko Mirror
|
||
|
email = emiliko@mami2.moe
|
||
|
signingkey = ABCDEF1234567890
|
||
|
[commit]
|
||
|
gpgsign = true
|
||
|
```
|
||
|
|
||
|
## Encryption
|
||
|
Gpg can encrypt pretty much anything. Consider bundling into a tarball
|
||
|
beforehand if it's more than one file
|
||
|
|
||
|
The `-a/--armor` flag will make sure the encrypted file is made up entirely of
|
||
|
ascii characters, which is easier to copy/paste than binary nonsense
|
||
|
|
||
|
Encryption can be symmetric or asymmetric. Symmetric encryption uses 1 key and a
|
||
|
password to encrypt. To decrypt, use the same key and re-enter the same
|
||
|
password
|
||
|
|
||
|
### Symmetric encryption
|
||
|
Symmetric encryption uses 1 key and 1 password to encrypt. To decrypt, you'll
|
||
|
need the same key and the same password
|
||
|
|
||
|
### Asymmetric encryption
|
||
|
Asymmetric encryption is meant for sending to a specific receiver. It uses 1
|
||
|
public key to encrypt. To decrypt, you'll need the private key pair to that
|
||
|
public key. `pass` uses this one
|
||
|
|
||
|
```bash
|
||
|
gpg -e -o encrypted_file -r emiliko@mami2.moe secret_file
|
||
|
# Then emiliko can decrypt it with her private key
|
||
|
gpg -d -o secret_file encrypted_file
|
||
|
```
|
||
|
|
||
|
## Moving keys
|
||
|
You'll want to export your keys to other devices. Ideally, you'd only export
|
||
|
subkeys and not the primary key. The primary key should be stored offline and
|
||
|
used to generate revocation certificates for compromised subkeys
|
||
|
|
||
|
```bash
|
||
|
gpg -o pub_key.pgp -a --export emiliko@mami2.moe
|
||
|
gpg -o sec_key.pgp -a --export-secret-key emiliko@mami2.moe
|
||
|
|
||
|
scp pub_key.gpg emiliko@192.168.0.1:/tmp/safe_directory
|
||
|
scp sec_key.gpg emiliko@192.168.0.1:/tmp/safe_directory
|
||
|
|
||
|
gpg --import pub_key.gpg
|
||
|
gpg --import sec_key.gpg
|
||
|
|
||
|
```
|
||
|
A safer method skips the creation of any intermediary files by sending it
|
||
|
through ssh right away
|
||
|
|
||
|
```bash
|
||
|
gpg --export-secret-key <user-id> | ssh emiliko@192.168.0.1 'gpg --import'
|
||
|
# Or if you're on the receiving system
|
||
|
ssh emiliko@192.168.0.1 'gpg --export-secret-key emiliko@mami2.moe' | gpg --import
|
||
|
```
|
||
|
|
||
|
In either case, or actually whenever importing your keys, you'll need to edit
|
||
|
the trust level after importing it
|
||
|
|
||
|
```bash
|
||
|
gpg --list-keys # Get the Key ID here
|
||
|
gpg --edit-key <user-id>
|
||
|
> trust
|
||
|
> 5 # If it's your own key
|
||
|
> y
|
||
|
> quit
|
||
|
```
|
||
|
|
||
|
For use with `pass`, you can check if your encryption key is working by trying
|
||
|
to add a new password, like `pass insert -e something` and see if it succeeds
|
||
|
|
||
|
## Backing up keys
|
||
|
Keys should be backed up on offline, physically inaccessible, media. Usb sticks
|
||
|
you leave at home or a piece of paper are both good choices. For the paper
|
||
|
version see `paperkey`
|
||
|
|
||
|
```bash
|
||
|
gpg -o /run/media/my_usb/keys.gpg --export-options backup --export-secret-keys emiliko@mami2.moe
|
||
|
```
|
||
|
|
||
|
Now later, or on another device, you can restore these keys
|
||
|
|
||
|
```bash
|
||
|
gpg --import-options restore --import keys.gpg
|
||
|
```
|
||
|
|
||
|
Then edit the trust level, as with the other transfer methods
|