GPG Keys for Yubikey and SSH Guide
Posted on March 04, 2025 in Tech-Recipe
[!NOTE] The environment used for this was: Linux i7 16Gb Debian 12.9
Stop GPG using GUI to prompt for passphrase
Do this:
sudo apt install pinentry-tty
sudo update-alternatives --set pinentry /usr/bin/pinentry-tty
GPG Defaults
Use this file in ~/.gnupg/gpg.conf
:
# https://github.com/drduh/config/blob/master/gpg.conf
# https://www.gnupg.org/documentation/manuals/gnupg/GPG-Options.html
# 'gpg --version' to get capabilities
# Use AES256, 192, or 128 as cipher
personal-cipher-preferences AES256 AES192 AES
# Use SHA512, 384, or 256 as digest
personal-digest-preferences SHA512 SHA384 SHA256
# Use ZLIB, BZIP2, ZIP, or no compression
personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed
# Default preferences for new keys
default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed
# SHA512 as digest to sign keys
cert-digest-algo SHA512
# SHA512 as digest for symmetric ops
s2k-digest-algo SHA512
# AES256 as cipher for symmetric ops
s2k-cipher-algo AES256
# UTF-8 support for compatibility
charset utf-8
# No comments in messages
no-comments
# No version in output
no-emit-version
# Disable banner
no-greeting
# Long key id format
keyid-format 0xlong
# Display UID validity
list-options show-uid-validity
verify-options show-uid-validity
# Display all keys and their fingerprints
with-fingerprint
# Display key origins and updates
#with-key-origin
# Cross-certify subkeys are present and valid
require-cross-certification
# Enforce memory locking to avoid accidentally swapping GPG memory to disk
require-secmem
# Disable caching of passphrase for symmetrical ops
no-symkey-cache
# Output ASCII instead of binary
armor
# Enable smartcard
use-agent
# Disable recipient key ID in messages (breaks Mailvelope)
throw-keyids
# Default key ID to use (helpful with throw-keyids)
#default-key 0xFF00000000000001
#trusted-key 0xFF00000000000001
# Group recipient keys (preferred ID last)
#group keygroup = 0xFF00000000000003 0xFF00000000000002 0xFF00000000000001
# Keyserver URL
#keyserver hkps://keys.openpgp.org
#keyserver hkps://keys.mailvelope.com
#keyserver hkps://keyserver.ubuntu.com:443
#keyserver hkps://pgpkeys.eu
#keyserver hkps://pgp.circl.lu
#keyserver hkp://zkaan2xfbuxia2wpf7ofnkbz6r5zdbbvxbunvp5g2iebopbfc4iqmbad.onion
# Keyserver proxy
#keyserver-options http-proxy=http://127.0.0.1:8118
#keyserver-options http-proxy=socks5-hostname://127.0.0.1:9050
# Enable key retrieval using WKD and DANE
#auto-key-locate wkd,dane,local
#auto-key-retrieve
# Trust delegation mechanism
#trust-model tofu+pgp
# Show expired subkeys
#list-options show-unusable-subkeys
# Verbose output
#verbose
Generate Master Key
Do this:
gpg --quick-generate-key \
'Your Name <your.email@example.com> (optional comment)' \
ed25519 cert never
You will see an output like this:
gpg: directory '/home/jas/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/jas/.gnupg/openpgp-revocs.d/03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC.rev'
public and secret key created and signed.
pub ed25519/0x9A2A84EDC48BBCFC 2025-03-04 [C]
Key fingerprint = 03A9 9DA4 A0BA 3F8E DBCD 7ECF 9A2A 84ED C48B BCFC
uid Jas Powell <jas@example.com>
Giong forward, we are interested in this number, the key fingerprint: 03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC
Add Subkeys
Now add subkeys for signing, encryption, and authentication. These will have expiration times to allow for key rotation. For example, using a one year expiration time:
gpg --quick-add-key 03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC ed25519 sign 1y
gpg --quick-add-key 03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC cv25519 encr 1y
gpg --quick-add-key 03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC ed25519 auth 1y
Verify the Keys
Now check you have the keys with command: gpg -K
gpg -K
/home/jas/.gnupg/pubring.kbx
----------------------------
sec ed25519/0x9A2A84EDC48BBCFC 2025-03-04 [C]
Key fingerprint = 03A9 9DA4 A0BA 3F8E DBCD 7ECF 9A2A 84ED C48B BCFC
uid [ultimate] Jas Powell <jas@example.com>
ssb ed25519/0xB6DFDCDABFB9E3CF 2025-03-04 [S] [expires: 2026-03-04]
ssb cv25519/0x6A481E53769ECDF3 2025-03-04 [E] [expires: 2026-03-04]
ssb ed25519/0x86EB33B0EF885886 2025-03-04 [A] [expires: 2026-03-04]
Export Master Keys
gpg --export-secret-keys 03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC > jas@example.com.private.gpgkey
gpg --export 03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC > jas@example.com.public.gpgkey
cp /home/jas/.gnupg/openpgp-revocs.d/03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC.rev jas@example.com.revocs.gpgkey
Don't lose these three files, these are the master keys for the laptop. Keep them in a sock drawer, in case you need to cut new subkeys after expiry.
Detatch Master Signing Key from the Master
gpg --export-secret-subkeys jas@example.com > jas@example.com.private.gpgsubkeys
gpg --delete-secret-key jas@example.com
gpg --import jas@example.com.private.gpgsubkeys
Next time you need to re-install your laptop, use the command:
gpg --import jas@example.com.private.gpgsubkeys
Key Check
And now we have a detatched signing key, we can check with: gpg -K
gpg -K
/home/jas/.gnupg/pubring.kbx
----------------------------
sec# ed25519/0x9A2A84EDC48BBCFC 2025-03-04 [C]
Key fingerprint = 03A9 9DA4 A0BA 3F8E DBCD 7ECF 9A2A 84ED C48B BCFC
uid [ultimate] Jas Powell <jas@example.com>
ssb ed25519/0xB6DFDCDABFB9E3CF 2025-03-04 [S] [expires: 2026-03-04]
ssb cv25519/0x6A481E53769ECDF3 2025-03-04 [E] [expires: 2026-03-04]
ssb ed25519/0x86EB33B0EF885886 2025-03-04 [A] [expires: 2026-03-04]
Notice the sec#
<- this indicates that the signing key is detached, and using the subkey.
The associated public keys are listed:
gpg -k
/home/jas/.gnupg/pubring.kbx
----------------------------
pub ed25519/0x9A2A84EDC48BBCFC 2025-03-04 [C]
Key fingerprint = 03A9 9DA4 A0BA 3F8E DBCD 7ECF 9A2A 84ED C48B BCFC
uid [ultimate] Jas Powell <jas@example.com>
sub ed25519/0xB6DFDCDABFB9E3CF 2025-03-04 [S] [expires: 2026-03-04]
sub cv25519/0x6A481E53769ECDF3 2025-03-04 [E] [expires: 2026-03-04]
sub ed25519/0x86EB33B0EF885886 2025-03-04 [A] [expires: 2026-03-04]
Caution
A word of advice though, all of this is security theatre. Even though we set up our algorithms, I can still see this:
gpg --edit-key 03A99DA4A0BA3F8EDBCD7ECF9A2A84EDC48BBCFC
Secret subkeys are available.
pub ed25519/0x9A2A84EDC48BBCFC
created: 2025-03-04 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/0xB6DFDCDABFB9E3CF
created: 2025-03-04 expires: 2026-03-04 usage: S
ssb cv25519/0x6A481E53769ECDF3
created: 2025-03-04 expires: 2026-03-04 usage: E
ssb ed25519/0x86EB33B0EF885886
created: 2025-03-04 expires: 2026-03-04 usage: A
[ultimate] (1). Jas Powell <jas@example.com>
gpg> showpref
[ultimate] (1). Jas Powell <jas@example.com>
Cipher: AES256, AES192, AES, 3DES
AEAD:
Digest: SHA512, SHA384, SHA256, SHA1
Compression: ZLIB, BZIP2, ZIP, Uncompressed
Features: MDC, AEAD, Keyserver no-modify
gpg> quit
I have no idea what SHA1 and 3DES are doing on that list. In 2025. GPG is broken.