GPG and Friends
Encryption and Decryption
gpg --encrypt --recipient <email-address> --output <file>.gpg <file>
gpg --decrypt --output <file> <file>.gpg
Receive Key
gpg --keyserver keyserver.ubuntu.com --recv-keys 407260f7616ece4d9d12462798e9740dc34539e0
Send Key
gpg --keyserver keyserver.ubuntu.com --send-keys DEFD03E63B265010AA4DCE9DA875049861C3818F
Bulk recieve keys and give marginal trust
declare -a arr=(98E9740DC34539E0 0EB3E83D29117223 6569D855A744BE93 052F367018D5C3D8 F32172599D8D2E97 611FBDECD5946E0F 45BCE75B840B1F69 F498D2D9DE7DAD9C 906788EB31A737FF 6D4A7990BDE2CC66 CD432CBF707904EC D9BDA4C843430A68 8A8F7B1C00993172 0DC98647D37D791E 538B7C0DCCB5A3C9 67419E45C3399EDD 6B5F8F2FE775FC48 EDD0EA1FDFCFE8FA 13498F032CCFE9DA 96F770C739BC5ACE A875049861C3818F EC873ACED468723C 080BCAD50BC3E920 56383E35D153B8B2 58DAD120A6939167 46D98A9C81D6DFDE 8469974868A49E75 EC3B6B6A6F60C8C3 C6602BC7B86A3ED0 4183D73BA439175B 738BDD02ABDD96C6 33D6780C08BD8BCD F0B61460B04C4B56 27BC4FFA445939B8 0BE76EF9F3A3884C 199C5BF4DFD60328 DE05D098EFD3AF7C)
for key in "${arr[@]}"
do
gpg --keyserver keyserver.ubuntu.com --recv-keys $key
# give marginal trust
echo -e "3\nquit" | gpg --command-fd 0 --edit-key $key trust
done
Export Public Key
gpg --armor --export A875049861C3818F
Creation ∨ Rotation of Keys
Daniel Pecos Martínez’ How to rotate your OpenPGP / GnuPG keys (archive.org) succinctly describes creating keys, adding multiple uids, creating subkeys, rotating keys, revoking keys, publishing keys, offline backup, and using subkeys so that laptop key exposure does not compromise the main key and the web of trust which has grown. Consider also adding an authentication subkey (gpg --edit-key --expert <key-id>
, addkey
, 8
, s
, e
, a
, q
, and save
).
nb: “Verify that gpg -K
shows a sec#
instead of just sec for your private key. That means the secret key is not really there.” - Debian Wiki
My next subkey rotation
Luci Stanescu shared his process, which generates subkeys directly on the YubiKey. This is advantageous for creating an attestation certificate, which relies on the subkeys only ever existing on the YubiKey.
Very loose notes:
- use a live boot cd as an airgap
- generate a main key (if needed)
gpg --expert --full-generate-key
- only allow the main key to certify keys, signing is not needed (principle of least privilege)
- configure card with
gpg --expert --card-edit
- enter
admin
- save setting
pass
for last, to avoid entering PINs during init config - set basics. e.g.,
name
,url
, etc - setup derived keys:
kdf-setup
- set
key-attr
for ed25519 etc
- enter
gpg --expert --edit-key <FP>
andaddcardkey
- create a signing key
- setup expiry to 396d, which gives a 1y overlap and is max allowed length for web certs
- create an encryption key on airgap
- it is okay to lose signing key, but we want an encryption backup
- create a signing key
- the cards piv can be used for ssh auth
- set
ykman opengpg keys set-touch sig fixed
on
can be changed tooff
,fixed
cannot- this metadata is present in the attestation cert
- physically print revocation key
- to export use
gpg --export-secret-keys --armor --export-options export-backup <FP>
- use
--export-options
to backup key metadata
- use
- delete secret key through gpg-agent:
gpg-connect-agent 'DELETE_KEY <key-grip>' /bye
- using
gpg --delete-secret-keys
appears to be fine now
- using
- export everyday use laptop keys
gpg --expoert-secret-keys --armor --export-options export-backup <FP> >for-everyday-use.gpg
YubiKey
See drduh’s YubiKey-Guide and Chip Senkbeil’s YubiKey blogposts. Notes based on these.
Reset a YubiKey
Yubico’s Resetting the OpenPGP Application on the YubiKey
Set YubiKey basics
$ gpg --expert --edit-card
admin
passwd
# set PIN and Admin PIN
# defaults are 123456 and 12345678
help
# set other info, like name
name
Transfer Subkeys to Yubikey
$ gpg --expert --edit-key
key 1
keytocard
key 1
key 2
keytocard
key 2
key 3
keytocard
q
y
Configure modes
Disable NFC:
ykman config nfc --disable-all
Require touch:
ykman openpgp keys set-touch sig fixed
ykman openpgp keys set-touch enc fixed
ykman openpgp keys set-touch aut fixed
Configure Git and Github
Get keygrip of auth key gpg -K --with-keygrip
, set in ~/.gnupg/sshcontrol
, set enable-ssh-support
in ~/.gnupg/gpg-agent.conf
, and reset gpg agent: gpgconf --kill all
. Add to env export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
. Get auth key from card: ssh-add -L
Update GitHub settings for keys with both GPG and SSH keys.
$ cat ~/.gitconfig
[user]
email = [email protected]
name = Mark Esler
signingkey = 0xa875049861c3818f
[commit]
gpgsign = true
Rotate pass
To update key of pass:
pass init <new-key>
Change Yubikeys with identical subkeys
Change selected card keygrip:
gpg-connect-agent 'scd serialno' 'learn --force' /bye
nb: this is not necessary if you just use seperate subkeys
Forget card
From How to make “gpg –card-status” forget an old card.
gpg-connect-agent 'KEYINFO --list' /bye
rm ~/.gnupg/private-keys-v1.d/KEYINFO-FOO.key
Harden GnuPG Configuration
From Kazutoshi Noguchi’s GnuPG Hardening set ~/.gnupg/gpg.conf
to:
cert-digest-algo SHA512
# override recipient key cipher preferences
# remove 3DES and prefer AES256
personal-cipher-preferences AES256 AES192 AES CAST5
# override recipient key digest preferences
# remove SHA-1 and prefer SHA-512
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
# remove SHA-1 and 3DES from cipher preferences of newly created key
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
# reject SHA-1 signature
weak-digest SHA1
# never allow use 3DES
disable-cipher-algo 3DES
# use AES256 when symmetric encryption
s2k-cipher-algo AES256
# use SHA-512 when symmetric encryption
s2k-digest-algo SHA512
# mangle password many times as possible when symmetric encryption
s2k-count 65011712
# both short and long key IDs are insecure
keyid-format none
# use full fingerprint instead
with-subkey-fingerprint
Also see YubiKey-Guide on GnuPG hardening.
nb: there is a small typo in Noguchi’s post.
SHA-512
should beSHA512
on line 18.
Unattended Key Creation
See GnuPG’s documentation on Unattended key generation for more info.
gpg --batch --gen-key <<EOF
Key-Type: RSA and RSA
Key-Length: 4096
Name-Real: Mark Esler
Name-Email: [email protected]
Expire-Date: 1y
EOF
gpg --quick-add-uid <key-id> "Mark Esler <[email protected]>"
gpg --quick-set-primary-uid <key-id> "Mark Esler <[email protected]>"
Key Signing Party 🥳
- Ask for a passport (or similar) if it is your first time signing someones keys.
- Do not upload keys you sign. Send signed keys to the owners email address.
- Sign and send each UID individually.
caff
+msmtp
To get all sigs of a key:
gpg --keyserver-options no-self-sigs-only --keyserver keyserver.ubuntu.com --allow-weak-key-signatures --recv-keys $KEY
More References
- 2006 Debian Keysigning party interviews
- Debian Keysigning Wiki
- Anatomy of a GPG Key - David Steele
- I’m giving up on PGP - Filippo Valsorda
- Attending a PGP / GnuPG signing party - Daniel Pecos Martínez
- Evil 32: Check Your GPG Fingerprints
- wotmate