6.3 KiB
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 for a
cheat sheet, the Archwiki for a
technical explanation and the Debian wiki 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:
$ 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:
> 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
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
[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
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
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
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
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
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
gpg --import-options restore --import keys.gpg
Then edit the trust level, as with the other transfer methods