Signing and verifying GPG keys is how you establish trust in the GPG Web of Trust model. It’s not about the key itself being inherently trustworthy, but about other people you trust vouching for that key’s authenticity.

Let’s see this in action. Imagine you’ve just received a GPG public key from alice@example.com. You want to verify it’s really Alice’s key and not an imposter’s.

# First, import Alice's public key
gpg --import alice_public_key.asc

# Now, list the keys in your keyring and find Alice's
gpg --list-keys alice@example.com

# You'll see output like this:
# pub   rsa2048/0xDEADBEEF 2023-10-27 [SC]
#       ABCDEF1234567890ABCDEF1234567890ABCDEF12
# uid   Alice <alice@example.com>
# sub   rsa2048/0xCAFEBABE 2023-10-27 [E]

The pub line shows the key ID 0xDEADBEEF. The long string below is the full fingerprint. You must verify this fingerprint through an independent, trusted channel.

How do you verify?

  1. Directly: If Alice is physically present, you can compare the fingerprint displayed by your gpg --list-keys command with the fingerprint she shows you on her own device.
  2. Trusted Communication: You could ask Alice to send you her fingerprint via a secure, encrypted chat or email that you already trust.
  3. Trusted Third Party: If you trust Bob, and Bob has already verified Alice’s key and signed it, you can trust Alice’s key based on Bob’s vouching.

Once you’ve independently verified the fingerprint, you can tell GPG that you trust this key. This is done by "signing" the key on your local machine. This doesn’t mean Alice signed it; it means you are attesting to its authenticity based on your verification.

# Sign Alice's key on your local keyring
gpg --sign-key alice@example.com

GPG will ask you to confirm. After you confirm, you’ll see an updated gpg --list-keys output:

# pub   rsa2048/0xDEADBEEF 2023-10-27 [SC]
#       ABCDEF1234567890ABCDEF1234567890ABCDEF12
# uid                 Alice <alice@example.com>
# sig          0xYOURKEYID/0xYOURKEYID 2023-10-28 [ULT]
# sub   rsa2048/0xCAFEBABE 2023-10-27 [E]

Notice the new line starting with sig. This shows that your key (0xYOURKEYID) has signed Alice’s key. The [ULT] indicates you’ve given it ultimate trust. You can also assign different trust levels ([FULL], [DELEGATING], [MARGINAL], [NONE]).

Building the Web of Trust:

The real power comes when you sign other people’s keys after verifying them, and they sign yours. If you trust Bob, and Bob trusts Alice, and you sign Alice’s key because you verified it yourself, then Bob can see that you (whom he trusts) have also vouched for Alice. GPG can then use this chain of trust to verify keys even if you’ve never met the key owner directly.

The gpg --edit-key alice@example.com command is your Swiss Army knife for managing trust. Once inside this interactive prompt, you can:

  • sign: Sign the key.
  • trust: Set the trust level for this key (e.g., full, marginal).
  • lsign: Locally sign the key (this is what --sign-key does, but you can do it interactively).
  • check: Verify the signature you have on a key.

The most surprising thing about the Web of Trust is that GPG’s default behavior is to not trust any key you import, even if it’s signed by many people. You have to explicitly tell GPG what your trust level is for a given key, or rely on GPG’s check command to see who has signed it and then decide if you trust those signers. You can also publish your own signed keys to a public keyserver, allowing others to verify keys you’ve vouched for.

The next step after building a local web of trust is understanding how to export your signed keys and import keys signed by others to extend your trust network.

Want structured learning?

Take the full Cryptography course →