Skip to content

Instantly share code, notes, and snippets.

@al-maisan
Last active March 24, 2026 16:45
Show Gist options
  • Select an option

  • Save al-maisan/9891822b17fc5aaf656c9002baa1f0e9 to your computer and use it in GitHub Desktop.

Select an option

Save al-maisan/9891822b17fc5aaf656c9002baa1f0e9 to your computer and use it in GitHub Desktop.
key signing procedure for next lunch

key signing procedure for next lunch

GPG Key Exchange & Signing — In-Person with Signal

A step-by-step guide for three people meeting in person who already have verified Signal chats with each other.

Overview

The goal is to verify each other's GPG public key fingerprints in person, then sign each other's keys to build a web of trust. Signal provides a second authenticated channel for exchanging data before and after the meeting.


Phase 1: Before the Meeting

Each person does the following independently.

Step 1 — Find your key fingerprint

gpg --fingerprint your@email.com

This prints something like:

pub   ed25519 2024-01-15 [SC]
      A1B2 C3D4 E5F6 7890 1234  5678 9ABC DEF0 1234 5678
uid           [ultimate] Your Name <your@email.com>

The 40-character hex string (A1B2 C3D4 ...) is your fingerprint.

Step 2 — Send your fingerprint to both friends via Signal

Copy the full fingerprint and send it in your verified Signal chat with each friend. This gives everyone a trusted reference to check against in person.

Step 3 — Export your public key

gpg --export --armor your@email.com > my_pubkey.asc

Send this file to both friends via Signal so they can import it before or during the meeting.

Step 3a — Generate a QR code of your fingerprint (optional)

gpg --fingerprint --with-colons your@email.com \
  | awk -F: '/^fpr:/{print $10; exit}' \
  | qrencode -t PNG -o my-fingerprint-qr.png

Save the QR image to your phone. This can speed up fingerprint verification at the meeting (see Step 4).

Prerequisite: install qrencode — available via apt install qrencode, brew install qrencode, etc.


Phase 2: At the Meeting (the critical step)

This is where the actual trust is established.

Step 4 — Verify fingerprints face-to-face

Each person pulls up their own fingerprint (on a terminal or phone screen) and reads it aloud while the other two check it against what was received over Signal.

QR alternative: instead of reading 40 hex characters aloud, display your fingerprint QR code (from Step 3a) on your phone screen and let the others scan it. They compare the scanned value against what they received over Signal. This is faster and eliminates misheard characters (e.g. "B" vs "D", "F" vs "S").

Go through all three people. Confirm every character matches.

Why this matters: an attacker would need to compromise both Signal and your in-person conversation simultaneously to substitute a fake key. This two-channel verification is what makes the process secure.

Step 5 — Exchange public keys (if not already done)

If you haven't already sent key files over Signal, do it now. Any transfer method works (Signal, USB stick, AirDrop, QR code) — the fingerprint verification in Step 4 is what authenticates the key, not the transport.


Phase 3: After the Meeting

Each person does the following for each of the other two friends.

Step 6 — Import their public key

gpg --import friend_pubkey.asc

Step 7 — Verify the fingerprint one more time

gpg --fingerprint friend@email.com

Confirm it matches what you verified in person. Do not skip this.

Step 8 — Sign their key

gpg --sign-key friend@email.com

GPG will show the key details and ask you to confirm. Type y to proceed.

This signature says: "I have personally verified that this key belongs to this person."

Step 9 — Export the signed key and send it back to the owner

gpg --export --armor friend@email.com > friend_signed.asc

Send friend_signed.asc back to the key owner via Signal.

Optional but recommended: encrypt the signed key to the friend before sending. This proves they control the corresponding private key (they must decrypt it to import your signature):

gpg --export --armor friend@email.com \
  | gpg --encrypt --armor -r friend@email.com \
  > friend_signed_encrypted.asc

Step 10 — Import signatures others made on your key

When you receive signed copies of your own key back from your friends:

# if they encrypted it to you
gpg --decrypt friend_signed_encrypted.asc | gpg --import

# if they sent it in the clear
gpg --import my_key_signed_by_friend.asc

Step 11 (optional) — Publish your now-signed key to a keyserver

gpg --send-keys YOUR_KEY_ID

This makes your key (with the new signatures) available to others.


Summary of Who Does What

Step Who Action
1-3a Everyone, before meeting Export fingerprint + public key, send via Signal, optionally generate QR
4-5 Everyone, at meeting Verify fingerprints (aloud or via QR scan), cross-check against Signal
6-8 Everyone, after meeting Import keys, verify fingerprints, sign keys
9 Everyone, after meeting Send signed keys back to owners via Signal
10 Everyone, after meeting Import signatures on your own key
11 Everyone, optional Upload signed key to keyserver

Why This Works

  • In-person verification defeats remote man-in-the-middle attacks
  • Verified Signal chat provides a second independent authenticated channel
  • The fingerprint check is the security-critical operation — key transport can use any channel
  • Each person ends up with two signatures on their key, strengthening their position in the web of trust
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment