· · 14 min leestijd Advanced

Quantum-safe GPG-identiteit met meerdere aliassen

Je GPG-identiteit is een van de weinige dingen die AI niet kan vervalsen. Eén offline master, drie aliassen, post-quantum encryptie, gelaagde backups.

Een hoofdsleutel in een kluis, drie sleutels aan haar ring, en een kat van ruis die haar gezicht niet kan kopiëren

TL;DR Eén GPG-masterkey die alleen certificeert, offline. Drie aliassen eraan gebonden, zodat iedereen kan nagaan dat het dezelfde persoon is. Ed25519-subkeys voor signing en SSH, een ML-KEM-plus-X448-subkey voor encryptie zodat opgenomen ciphertext dicht blijft als er een quantumcomputer komt, en drie backups die er elk van uitgaan dat de andere twee weg zijn. Vereist GnuPG 2.5.

Een cryptografische signature betekent nog steeds precies wat er staat. Is de key van jou en klopt de signature, dan komt de inhoud van jou. Geen vendor heeft je die identiteit gegeven, geen CA kan hem intrekken, geen platform kan hem schorsen. Hij bestaat omdat jij de key hebt gegenereerd, en hij is van jou zolang jij de private helft in handen hebt. Het meeste wat “online identiteit” heet is geleend. Een handle die iemand kan bannen, een e-mailadres dat de domeineigenaar terugpakt op de dag dat het hem uitkomt. Een GPG-signature staat daar helemaal buiten.

Jarenlang was dat iets waar crypto-nerds om gaven en verder bijna niemand. Dat verandert, en sneller dan ik had gedacht. Vroeger nam ik aan dat de mens achter een mail of een commit ook een mens was, en waarschijnlijk degene die in de headers stond. Dat doe ik niet meer. AI-gegenereerde tekst, stem en video worden alsmaar goedkoper, en de resultaten zitten al in m’n inbox. PR-berichten die de stijl van een maintainer naapen. Een synthetisch telefoontje van een “collega” die om een gunst vraagt. Bewijzen dat jij die post schreef of die commit pushte is niet meer gratis. Een signature is het ene ding in die stapel dat niet na te maken is zonder eerst jouw key te stelen.

Er zit een tweede druk op dezelfde setup, trager en veel verder weg. Duikt er ooit een quantumcomputer op die groot genoeg is, dan wordt alles wat je ooit met klassieke public-key-cryptografie versleutelde achteraf leesbaar. Dat heet harvest-now-decrypt-later, en van statelijke actoren wordt aangenomen dat ze het al doen. Ze nemen je versleutelde verkeer vandaag op en gaan erop zitten, met het plan om het over tien of twintig jaar te kraken zodra de hardware er is. De ciphertext die je al lekte krijg je niet terug. Wel kun je stoppen met de stapel groter maken, en dat betekent nu post-quantum encryptie, terwijl de tooling nog wat ruw is.

Dus dit is de vraag waar het mij om gaat. Houdt de GPG-setup die je nu hebt over tien jaar nog stand? Attributie is vandaag al een probleem. Vertrouwelijkheid op de lange termijn wordt er later een. Een key die je vandaag genereert moet allebei overleven.

Deze post is de setup waar ik op uitkwam na een tijdje op die vraag kauwen. Eén offline masterkey, drie identiteitsaliassen eraan gekoppeld, post-quantum encryptie via ML-KEM (Kyber), en drie onafhankelijke backup-lagen. Hij loopt lang, want elke keuze hier is een afweging en die redenering is het deel dat het lezen waard is. Nieuw met GPG? Lees dan eerst GPG uitgelegd. Vanaf hier ga ik ervan uit dat je ooit minstens één key hebt gegenereerd.

Wat we gaan bouwen

[Masterkey - Ed25519 - Certify only]    ← offline, in een kluis, op papier
 │
 ├── UID 1: Tom Herder  <tom@byteherder.com>
 ├── UID 2: kapott       <kapott@pm.me>
 ├── UID 3: Tom Meurs    <tom.meurs@gmail.com>
 │
 ├── [Sub 1 - Ed25519]        [S]  Sign    → e-mail en git
 ├── [Sub 2 - ML-KEM+X448]    [E]  Encrypt → quantum-safe
 └── [Sub 3 - Ed25519]        [A]  Auth    → SSH login

Eén root, drie identiteiten, drie subkeys. Waarom zo opdelen?

KeuzeReden
Masterkey = certify-onlyDe master ondertekent alleen andere keys en identiteiten. Nooit voor e-mail, nooit voor git. Houd hem offline en je identiteit overleeft elke laptop-diefstal.
Aparte subkeys voor Sign / Encrypt / AuthJe kunt elke subkey los roteren of intrekken. Laptop gestolen? Subkeys revoken, identiteit behouden.
Meerdere UIDs op één keyAlle drie de aliassen zijn cryptografisch gebonden aan dezelfde master - bewijs dat ze van dezelfde persoon komen.
ML-KEM (Kyber) voor encryptieBeschermt tegen harvest-now-decrypt-later. Wie jouw ciphertext vandaag opneemt kan die in 2046 niet ontsleutelen met een quantumcomputer.
Ed25519 voor signing en authSignatures hebben geen harvest-probleem - die worden op het moment van ondertekenen geverifieerd. Volledig post-quantum signing (ML-DSA) staat in RFC 9580, maar tooling-support is in 2026 nog dun (Thunderbird, GitHub, SSH-servers). Ed25519 is de pragmatische keuze.

Eén afweging wil ik benoemen voordat je een commando kopieert. Zet je kapott@pm.me en tom.meurs@gmail.com op dezelfde key, dan is publiek aantoonbaar dat “kapott” en “Tom Meurs” dezelfde mens zijn. Prima als je attributie over je aliassen heen wilt. Gevaarlijk als kapott een pseudoniem moet blijven, want zodra die publieke key op een keyserver staat is de link permanent. Keyservers vergeten niks, en vragen helpt niet. Heb je een echt pseudoniem nodig, geef het dan een eigen key (scenario B verderop).

Wat je nodig hebt

GnuPG 2.5 of later. ML-KEM-subkeys genereren kan niet in 2.4.

# Arch
sudo pacman -S gnupg paperkey qrencode zbar diceware pwgen veracrypt

# Debian/Ubuntu - activeer de officiële GnuPG-repo voor 2.5.x
curl -fsSL https://repos.gnupg.com/GPG-KEY-gnupg.asc \
  | sudo tee /etc/apt/keyrings/gnupg.asc > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/gnupg.asc] https://repos.gnupg.com/debian bookworm main" \
  | sudo tee /etc/apt/sources.list.d/gnupg.list
sudo apt update && sudo apt install -y gnupg2 paperkey qrencode zbar-tools veracrypt diceware pwgen

Controleer:

gpg --version | head -2   # moet 2.5.x of later zijn

Genereer de keys op een schoon OS. Een Ubuntu live-USB of Tails is de paranoïde optie, en paranoïde is hier de juiste stand. Wat je dagelijkse laptop misschien stilletjes draait komt niet in de buurt van de master. Werk in een aparte GNUPGHOME, zodat hier niks van naar je bestaande keyring lekt:

mkdir -p ~/gpg-build && chmod 700 ~/gpg-build
export GNUPGHOME=~/gpg-build

GnuPG hardenen

Zet een hardened config in $GNUPGHOME/gpg.conf vóór je iets genereert. Die schakelt zwakke algoritmen uit en kiest moderne defaults:

cat > "$GNUPGHOME/gpg.conf" <<'EOF'
keyid-format 0xlong
with-fingerprint
with-subkey-fingerprint
list-options show-uid-validity

no-emit-version
no-comments
no-greeting
export-options export-minimal

personal-cipher-preferences  AES256 AES192 AES
personal-digest-preferences  SHA512 SHA384 SHA256
default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed

weak-digest SHA1
disable-cipher-algo 3DES
disable-cipher-algo CAST5
disable-pubkey-algo RSA1024

require-cross-certification
no-symkey-cache
throw-keyids

keyserver hkps://keys.openpgp.org
EOF

chmod 600 "$GNUPGHOME"/gpg.conf
gpgconf --kill gpg-agent && gpgconf --launch gpg-agent

Een passphrase die je onthoudt

De passphrase is het laatste wat tussen een aanvaller en je master staat zodra die een kopie van het versleutelde bestand heeft. Hij moet offline bruteforcen overleven door iemand met hardware die je niet kunt voorspellen. Gebruik Diceware, een willekeurige rij van zeven of meer woorden uit een grote lijst. Makkelijker te onthouden dan %Xh9$!Lq, en sterker.

diceware -n 8 -d ' ' --no-caps
# schemerig koning fiets bramboes tunnel ijverig mosterd kraaier

Schrijf hem op papier en leg dat papier ergens fysiek achter slot. Raak je de passphrase kwijt, dan is elke backup uit deze post oud papier.

Masterkey aanmaken

We willen Ed25519, certify-only, tien jaar.

gpg --expert --full-generate-key

Antwoorden: 11 (ECC met eigen capabilities) → s om Sign uit te zetten (alleen Certify blijft over) → q → 1 (Curve 25519) → 10y → je primaire UID (ik gebruik mijn echte naam en mijn echte adres). GPG vraagt twee keer om de passphrase en klaar.

Leg de fingerprint meteen vast, zodat de rest van de post $KEYID kan gebruiken:

export KEYID=$(gpg --list-secret-keys --with-colons | awk -F: '/^fpr/ {print $10; exit}')
echo "$KEYID" > ~/gpg-build/KEY_INFO.txt

UIDs toevoegen voor elk alias

gpg --expert --edit-key "$KEYID"

In de editor:

gpg> adduid      # Tom Herder <tom@byteherder.com>
gpg> adduid      # kapott <kapott@pm.me>
gpg> uid 1       # kies je primaire
gpg> primary
gpg> save

Elke UID is nu getekend door dezelfde master. Die handtekening is het bewijs dat ze bij één persoon horen.

Subkeys toevoegen

Nog steeds in --edit-key:

Signing-subkey (Ed25519): addkey → 10 (ECC sign only) → 1 → 2y.

Encryption-subkey - de post-quantum variant: addkey → 16 (ECC and Kyber) → 4 (Kyber 1024 + X448) → 2y.

Dit is het hybride stuk, en de reden dat je GnuPG 2.5 nodig had. De subkey last ML-KEM-1024 (NIST FIPS 203, quantum-safe) aan X448 (klassiek ECC) vast. Wie je ciphertext wil lezen moet allebei breken. Dus je bent gedekt wat er ook eerst valt, klassieke crypto voor een quantumcomputer of een gat dat iemand in ML-KEM zelf vindt.

Authentication-subkey (Ed25519): addkey → 11 (ECC custom) → s uit en a aan → q → 1 → 2y → save.

Controleer met gpg --list-secret-keys --with-subkey-fingerprint. Je hoort [C], [S], [E], [A] te zien bij master, sign, encrypt en auth.

Nu je hier toch bent, genereer meteen een revocation certificate. Dat is de noodrem voor de dag dat de masterkey gecompromitteerd is, en je maakt hem nu, terwijl de master nog voor je neus staat:

gpg --output "$GNUPGHOME/revocation-$KEYID.asc" --gen-revoke "$KEYID"

De master offline halen

Dit is de stap die de rest de moeite waard maakt. Exporteer alles, wis het master-secret uit de werkkeyring, en importeer alleen de subkey-secrets terug.

cd "$GNUPGHOME"

gpg --export-secret-keys    --armor --output MASTER-FULL.asc   "$KEYID"
gpg --export-secret-subkeys --armor --output SUBKEYS-ONLY.asc  "$KEYID"
gpg --export                --armor --output PUBLIC.asc         "$KEYID"
gpg --export-ownertrust > OWNERTRUST.txt

gpg --delete-secret-keys "$KEYID"
gpg --import SUBKEYS-ONLY.asc
gpg --import-ownertrust OWNERTRUST.txt

Controleer het resultaat:

gpg --list-secret-keys --with-subkey-fingerprint
# sec#  ed25519/0x...   [C]   ← de # betekent "master-secret niet aanwezig"
# ssb   ed25519/...     [S]
# ssb   ky1024_cv448/.. [E]
# ssb   ed25519/...     [A]

Die # is waar alles hierboven voor was. Je dagelijkse laptop draagt nu alleen nog vervangbare subkeys, dus die revoken na een diefstal kost je een paar minuten in plaats van je identiteit.

Drie backup-lagen

Eén backup is geen backup. Dus draai ik drie onafhankelijke paden, en elk gaat ervan uit dat de andere twee al kapot zijn op het moment dat ik ernaar grijp.

Hot - VeraCrypt-volume bij meerdere clouds. Altijd bereikbaar, overleeft een verloren laptop.

veracrypt --text --create cloud-backup/gpg-vault.vc \
  --volume-type=normal --size=128M \
  --encryption=AES-Twofish-Serpent --hash=Whirlpool \
  --filesystem=FAT --pim=0 --keyfiles="" \
  --random-source=/dev/urandom

sudo veracrypt --text --mount cloud-backup/gpg-vault.vc /tmp/vault --pim=0 --keyfiles=""
sudo cp MASTER-FULL.asc SUBKEYS-ONLY.asc PUBLIC.asc OWNERTRUST.txt \
        revocation-$KEYID.asc KEY_INFO.txt /tmp/vault/
sync && sudo veracrypt --text --dismount /tmp/vault

rclone copy cloud-backup/gpg-vault.vc gdrive:SecureBackups/
rclone copy cloud-backup/gpg-vault.vc proton:SecureBackups/

Geef het VeraCrypt-volume een andere passphrase dan je GPG-key, zodat één lek de ander niet meetrekt. De AES-Twofish-Serpent-cascade met een Argon2-afgeleide key houdt het ook tegen een quantumcomputer. Grover halveert de effectieve symmetrische sleutellengte, en dan houd je nog zo’n 128 bits marge over.

Cold - paperkey + QR-codes. Overleeft cloud-uitval en account-bans.

Paperkey haalt de redundante structuur uit een secret key en houdt alleen de bytes over die ertoe doen, precies wat je op archiefpapier wilt. Ed25519 kan het netjes aan. Kyber nog niet, dat is te nieuw en er is nog geen compacte encoding voor. Dus de master gaat via paperkey en de volledige armored export via QR-codes, verdeeld over meerdere PNG’s met hoge foutcorrectie.

# Paperkey voor de master
paperkey --secret-key <(gpg --export-secret-keys "$KEYID") \
         --output master.paperkey.txt

# QR-stapel voor de volledige bundle
split -b 1500 -d -a 2 MASTER-FULL.asc part_
i=1; total=$(ls part_* | wc -l)
for f in part_*; do
  qrencode -l H -s 10 -m 4 \
           -o "qr-$(printf '%02d' $i)-of-$(printf '%02d' $total).png" < "$f"
  i=$((i+1))
done

Test je restore voordat je erop vertrouwt:

for f in qr-*.png; do zbarimg --raw --quiet "$f" >> combined.asc; done
diff combined.asc MASTER-FULL.asc && echo "restore werkt"

Print op archiefpapier met een laserprinter, want inkjet-inkt vervaagt binnen tien jaar en langer dan dat meegaan is het punt. Leg de stapel in een brandwerende kluis, of verdeel hem over twee locaties als je het grondig wilt doen.

Hardware - YubiKey (optioneel). Dit dekt het vervelende geval waarin je backups lekken maar de fysieke token nog in je broekzak zit. In 2026 doet YubiKey-firmware nog geen PQC-subkeys, dus alleen de Ed25519 sign- en auth-subkeys gaan op de token en de Kyber-encrypt-subkey blijft in software. Yubico’s roadmap zet PQC voorzichtig op firmware 6 in 2027, dus dat gat zou dicht moeten gaan.

Identiteiten per werkgever

Klant- en werkgeverwerk geeft je twee scenario’s, en die keuze maak je liever bewust.

Scenario A - UID toevoegen aan de bestaande masterkey. Makkelijk, en het bewijst cryptografisch dat dezelfde persoon achter al je identiteiten zit. De adder onder het gras is dat elke collega die je werkgever-publickey importeert meteen de volledige lijst van je privé-aliassen krijgt. Prima voor tom@byteherder.com, dat is toch al m’n publieke identiteit. Een echt probleem voor kapott@pm.me.

Scenario B - aparte key per werkgever. Eén key extra om op te passen, maar de scheiding is schoon. Cross-signen met je hoofdmaster kan alsnog als je de attributie wilt, en doe je dat niet, dan blijven de identiteiten cryptografisch los van elkaar. Dit is mijn default zodra privacy per context ertoe doet.

export GNUPGHOME=~/gpg-dsm
mkdir -p "$GNUPGHOME" && chmod 700 "$GNUPGHOME"
gpg --expert --full-generate-key   # herhaal de §6–§8 flow

Houd per identiteit een eigen VeraCrypt-volume aan (dsm-vault.vc, klantX-vault.vc). Dezelfde drie backup-lagen als hierboven, met de blast radius per klant afgeschermd.

Dagelijks gebruik

Publiceer de publieke key. Keys.openpgp.org laat je elke UID per e-mail verifiëren voordat het iets publiceert, en dat is meteen een check dat je de adressen goed getypt hebt:

gpg --keyserver hkps://keys.openpgp.org --send-keys "$KEYID"

Git signing. Pin je commits op de signing-subkey. Die ! op het eind dwingt GnuPG om déze subkey te gebruiken in plaats van er zelf een te kiezen:

SIGNKEY=$(gpg --list-secret-keys --with-colons "$KEYID" \
          | awk -F: '/^ssb/ && $12~/s/ {print $5; exit}')

git config --global user.signingkey "$SIGNKEY!"
git config --global commit.gpgsign true
git config --global tag.gpgsign true

Met per-repo overrides sign je werkgever-commits met de werkgever-key:

git config user.email tom.meurs@dsm.com
git config user.signingkey "DSM_SIGNKEY!"

SSH via gpg-agent. Je auth-subkey wordt je SSH-key:

gpg --list-secret-keys --with-keygrip "$KEYID"   # noteer de keygrip van de A-subkey
echo "<KEYGRIP>" >> ~/.gnupg/sshcontrol

# In je shell rc
export GPG_TTY=$(tty)
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent

ssh-add -L   # plak deze regel in GitHub → SSH keys

E-mail. Zodra alle drie de adressen naar dezelfde masterkey wijzen, matcht Thunderbird de UID vanzelf op je From:-header. Mutt doet hetzelfde zodra je pgp_default_key = $KEYID zet.

Rotatie

Elke achttien maanden, ruim voordat de tweejaarsexpiry van de subkeys valt, haal ik de master een paar minuten terug en schuif ik de expiry weer op. Dezelfde VeraCrypt-mount-dans als bij de backups:

sudo veracrypt --text --mount ~/gpg-build/cloud-backup/gpg-vault.vc /tmp/vault
export GNUPGHOME=$(mktemp -d) && chmod 700 "$GNUPGHOME"
gpg --import /tmp/vault/MASTER-FULL.asc

gpg --expert --edit-key "$KEYID"
# key 1, key 2, key 3 → expire → 2y → save

gpg --export-secret-subkeys --armor "$KEYID" > ~/SUBKEYS-NEW.asc
rm -rf "$GNUPGHOME" && unset GNUPGHOME
sudo veracrypt --text --dismount /tmp/vault

GNUPGHOME=~/.gnupg gpg --import ~/SUBKEYS-NEW.asc
gpg --keyserver hkps://keys.openpgp.org --send-keys "$KEYID"

Lekt er ooit een subkey, dan is het dezelfde flow met één stap extra. revkey op de gecompromitteerde subkey, exporteren, publiceren. De master is nooit van z’n plek geweest, dus je identiteit blijft heel.

Het bredere principe

Minimaal is dit niet, en dat ga ik ook niet beweren. Zeven Diceware-woorden, drie backup-lagen, een terugkerend ritueel, een paar USB-sticks in verschillende laden. Je kunt het allemaal overslaan, je commits signen met de eerste de beste SaaS “identity service”, en nooit meer een woord over keyservers lezen.

De adder is dat een SaaS-identiteit van de provider is. Die kan hem intrekken of kwijtraken bij een incident. Die kan een bevel krijgen en hem afstaan. En op de dag dat ze hun businessmodel omgooien migreer jij op hun klok. Die controle-versus-gemak-vraag heb ik in Sovereign Infrastructure uitgewerkt. De root zelf bezitten kost me meer tijd dan een abonnement zou kosten. Wat ik ervoor terugkrijg is een identiteit die niet in een systeem zit dat ik niet kan openmaken en nakijken.

Attributie is hetzelfde argument, en dat speelt nu al. Als tekst, stem en video allemaal te faken zijn op hardware die iedereen kan kopen, is de eerlijke default voor elk bericht “kan iedereen zijn”. Je commits signen houdt niemand tegen die rotzooi in jouw naam wil produceren. Het geeft iedereen die het wil weten een manier om het na te kijken, en die check houdt stand ook als de vervalsing verder perfect is. Die check bestaat alleen als je al signde vóór de vervalsing opdook, dus begin nu.

Quantum-safety is hetzelfde argument, uitgerekt over decennia. Ik verwacht niet dat een quantumcomputer binnenkort m’n mail leest. Ik verwacht wel een geduldige tegenstander die vandaag mijn versleutelde verkeer opneemt en gokt dat de hardware later komt. De enige tegenzet is stoppen met ze ciphertext voeren die straks goedkoop te kraken is, en dat betekent nu post-quantum encryptie, ruwe tooling en al.

M’n master is offline sinds de dag dat ik hem genereerde. De subkeys op deze laptop verlopen over twee jaar en na achttien maanden haal ik de master terug om dat op te schuiven. De rest is papier in een kluis en een VeraCrypt-bestand bij twee clouds. Dat was er nodig voor een key waarvan ik verwacht dat hij in 2046 nog werkt.