TLDR
Let me keep it short: my old blog signing key (A61AF15A44205E4B2BABFEA09A92DEDB762B3A03
) is deprecated ahead of its October deathday, the new one is now a sub key set to expire on 2026-06-16 with the fingerprint of 58222FDBCBFB1D0D51AE0088C20D48DA42BADC2E
. Relevant part in /about is also updated so you can check that instead.
Intro
Like I said in /about, the site is GDPR compliant and I’ve turned all possible privacy enhanced options on in Hugo and umami to make it clutter-free, I really have no idea if anyone except me would use the signing key to check the page integrity. Anyway, it’s updated just in case.
This time I use a master/sub key strategy to minimize the influence should my private key gets exposed somehow. And to create the perfect1 GPG keychain, I followed 如何创建完美的 GPG 密钥对 and used my VM knowledge to take a step further.
How-To
Basically these parts:
- Create a up-to-date bootable Live CD/rootfs with custom packages
- Install the newly built system in a VM without Internet/Wi-Fi/Bluetooth/USB access to reduce potential attack surface
- Create and export the perfect GPG keychain in this offline VM, and save the backup in a secure place
- Import the subkey in new system and do some tests
- If everything is ok, wipe the data inside VM with
srm
orshred -zun 7
then destroy the VM
Details
xtools
from Void Linux offer a lot of useful commands which I use on a daily basis, and the other day I came across Unmasking the hidden gems of Void Linux and discovered xetcchanges
along with void-mklive. Although I’ve heard of it before, I did not realize that it was that easy to make a bootable Live CD with custom packages. And it just works without digging any further into the documentation.
git clone https://github.com/void-linux/void-mklive && cd void-mklive
sudo ./build-x86-images.sh -b base -- -a x86_64 \
-r 'https://repo-fi.voidlinux.org/current' \ # custom mirror
-p 'void-repo-nonfree void-release-keys xtools sudo opendoas
bash-completion bc bison ca-certificates curl dos2unix eza fzf gawk git git-lfs gnupg jc jq lsof man-db moreutils mosh nnn parallel pciutils pigz proxychains-ng psmisc rlwrap rsync tmux tree unar unzip vim wget zsh zsh-autosuggestions zsh-syntax-highlighting zstd
bsdtar fuse-sshfs lazygit ncdu2 pinentry-tty screenFetch tealdeer vim-colorschemes zsh-completions
minisign openbsd-netcat srm xz
bind-utils nss-mdns avahi avahi-utils
dkms linux-headers qemu-ga virtiofsd' \ # custom packages
-S 'avahi-daemon' \ # enable additional services
-T 'Custom Void Linux'
Now wait 10 minutes or so until the new Live CD is ready.
Boot it in an isolated offline VM, install the system and generate GPG keychain:
# Generate a 128-bit passphrase, the gold standard for passphrases
# The implementation seems to only use the first 128-bit so longer passphrases sound unnecessary
$ gpg --armor --gen-random 2 16
ioy6VimyqrrbluF/1GjgnA==
# run again for subkey
$ gpg --armor --gen-random 2 16
yz+4N5194QiOvK03/YWW+A==
# Generate master key
gpg --full-generate-key --homedir $HOME/.local/share/gnupg --pinentry-mode loopback
# Generate sign only sub-key
gpg --edit-key (tab)
addkey
10 ECC (sign only)
# key ABCDE1234567890
# passwd
save
# Export rev cert
gpg --output blog-rev.crt --gen-revoke F46CCB3B34CE01D7
# Armored public key
gpg --output blog-pub.asc --armor --export-options export-minimal --export "brand new blog signing key"
# Armored secret key
gpg --output blog-priv.asc --armor --export-secret-keys "brand new blog signing key"
# Pack
tar -czf gpg-blog.tar.gz blog-*
# Screw export
srm blog-*
# backup tarball elsewhere secure
mv gpg-blog.tar.gz /mnt/any/where/secure/
# export tmp keychain
gpg --export-secret-subkeys F46CCB3B34CE01D7 > subkeys
# delete master key
gpg --delete-secret-keys F46CCB3B34CE01D7
# import sub key
gpg --import subkeys
echo "'sec#' in output means the master key is no longer in the keychain."
echo "now backup tmp subkey and import it outside VM, test again just in case."
# screw tmp keychain
srm subkeys
srm ~/.local/share/gnupg/openpgp-revocs.d/3E8738B9*.rev
If you can’t make SSH work w/o Internet access for network adapters like host-only or internal network, try mounting the disk containing VM data in another isolated offline VM, and use that as a middleware.
Of course this is subjective and cryptography algorithms are evolving. The industry recommended RSA-2048 in the past, and now even RSA-4096 is sometimes replaced in favor of Elliptic Curve Cryptography (ECC). ↩︎