What a signature proves, and what it does not
Verification gets recommended constantly and explained rarely. People end up running the command as a ritual without a clear sense of what a GOOD result establishes. That gap is worth closing, because the difference between what signing proves and what people assume it proves is where the remaining risk lives.
#The claim a signature makes
A signature over a block of text establishes exactly two things. Whoever produced it held the private key matching a specific public key. And the text has not changed by a single character since they produced it.
That is the entire claim. It is narrow and it is absolute. There is no partial credit and no probabilistic element. Either the maths works out, in which case both statements hold, or it does not, in which case neither does.
Everything useful follows from chaining that claim to something you already trust. If you know the key belongs to the market, and the market signed a statement listing its current addresses, then a valid signature over that statement tells you the list is genuine and unmodified. The signature does not carry that trust on its own. It transfers trust you already had in the key.
#Which means the key comes first
This is the step people skip. Getting the key right is the part that requires care, and once it is done correctly it stays done. The fingerprint is the thing to pin, not the key file, because a fingerprint is short enough to compare by eye and long enough that nobody can produce a second key matching it.
Get the fingerprint from more than one place that would have to be compromised independently. Check it once, carefully, character by character rather than glancing at the first and last few. Then store it where you will find it later. After that, every future verification is mechanical and you never repeat this step. The getting started chapter walks through the commands.
The failure mode worth naming explicitly is accepting a key because it arrived alongside the thing it was meant to verify. A phishing page will happily serve you a key, a signed message, and instructions for checking one against the other, and all three will be internally consistent because the same person produced all three. Internal consistency is not evidence.
#The four ways it fails
GnuPG tells you which of these you are looking at, though the output is not always easy to read. They mean very different things.
| BAD signature | The maths does not work. The text was altered after signing, or the signature was fabricated. This is unambiguous and the only correct response is to leave. |
|---|---|
| No public key | The message was signed by a key you do not have. This is not a failure of the message, it is a gap in your keyring. Import the correct key, after checking its fingerprint, and try again. Do not import whatever key the page offers you. |
| GOOD signature, wrong key | The maths works, but against a key that is not the one you pinned. This is the dangerous one, because the word GOOD appears in the output. Always read which key ID signed, not just whether the word GOOD is present. |
| GOOD signature, stale content | Everything checks out but the signed statement is old. A signed message stays valid forever, so an attacker can replay a genuine old one. This is why signed statements carry a timestamp and why you have to actually look at it. |
The last two are the ones that catch experienced users, and both are defeated by the same habit. Read the output rather than pattern matching on the word GOOD. Two extra seconds.
#Replay, and why timestamps are in there
A signature has no expiry built into it. A statement signed two years ago verifies exactly as cleanly today as it did then, because nothing about it has changed. That property is what makes signatures useful for archives and what makes them awkward for anything about the present.
The fix is to put the time inside the signed text. Once the timestamp is part of what was signed, it cannot be adjusted without breaking the signature, so an attacker replaying an old statement is stuck presenting an old date. Then the question becomes whether you look at it. A signed statement dated eleven months ago verifying perfectly is telling you something was true eleven months ago, which is not the question you were asking.
This matters most around address rotation. A genuine, correctly signed roster from before a rotation lists an address that has since been retired. Everything about it verifies. It is simply out of date, and out of date rosters are precisely what gets replayed.
#Where verification stops helping
Being honest about the limits is more useful than overselling the tool.
- It says nothing about intent. A signature proves who wrote something, not that what they wrote is true or that they have your interests in mind.
- It says nothing about the machine you are on. If your own system is compromised, the verification runs on compromised hardware and can be made to say anything. Signature checking assumes a trustworthy local machine and cannot establish one.
- It does not cover what happens after. Verifying that you arrived at the right place says nothing about what happens in the session that follows.
- It does not survive key compromise. If the private key is in someone else's hands, everything they sign verifies correctly. This is what fingerprint rotation announcements are for, and why one arriving out of nowhere deserves more scepticism than usual, not less.
None of that argues against verifying. It argues for treating verification as one control among several rather than the whole of your defence. It reliably answers one question, which is whether you are where you think you are, and it answers that question better than anything else available. The security chapter covers the controls that sit around it.