Reading a PGP-Signed Advisory Correctly: Fingerprints, Timestamps and Revocation Notices
Most people stop at a green “Good signature” line. That is the wrong place to stop. A valid PGP signature on an advisory proves one narrow thing: a specific private key signed a specific block of text. It does not prove the key still belongs to the operator you think it does, that the text is current, or that the key has not been stolen. Fingerprints, timestamps, and revocation notices are how you close those gaps. This is verification hygiene for research. It is not a how-to for reaching live markets.
Directories and operators publish signed notes because a compromised web server is enough to swap every onion address on the page. The page itself is not evidence. The signature is, and only after you have authenticated the key out of band.
What a signed advisory actually is
PGP does two jobs. Encryption hides content. Signing authenticates it. You sign with a private key. Anyone with the matching public key can check the stamp. The usual analogy holds: a wax seal anyone can inspect and nobody can forge without the seal itself.
On the wire you will see ASCII armor. That is binary wrapped as copy-paste text. A clearsigned advisory starts with BEGIN PGP SIGNED MESSAGE. A detached signature is a separate BEGIN PGP SIGNATURE block next to the original file. A public key is a BEGIN PGP PUBLIC KEY BLOCK. If you cannot tell those three apart, you are not verifying anything. You are reading a forum post.
A typical workflow (GnuPG on a machine you control, not a random web form) is:
- Import the operator’s public key from a source you already trust.
- Confirm the full fingerprint against a second channel.
- Run gpg –verify on the advisory (or verify the detached signature against the exact file).
- Read the output for key id, timestamp, and any warning. Do not screenshot the first green line and walk away.
Browser PGP toys exist. Some even keep crypto in WebAssembly and claim nothing leaves the tab. Fine for learning armor format. Not fine as your only verifier for an advisory you will act on. You want a local keyring you can inspect, pin, and, when needed, revoke.
Fingerprints: the only identifier that matters
A key fingerprint is a short hex string that uniquely identifies a PGP key. It looks like A1B2 C3D4 E5F6 7890 1234 5678 9ABC DEF0 1234 5678. That is what you compare. Not the user id. Not the email field. Not the last eight hex characters someone pasted in a caption.
Short key IDs are a known collision problem. Treating the trailing 32 bits as identity is how you accept a lookalike key. Always display and compare the full fingerprint. In GnuPG that is gpg –fingerprint on the imported key, then a character-by-character check against a value you obtained some other way.
The other way is the whole point. Before you treat a public key as belonging to a directory or an admin, compare the fingerprint they give you in person, on a voice call, or through a channel you already authenticated. That step is what stops a man-in-the-middle from handing you a key they control and intercepting everything you encrypt to it. A signature check against a key you first saw on the same page as the advisory is circular. The attacker who defaced the page also published their key.
I treat a newly posted “official” key with no prior fingerprint as untrusted, even if the signature on today’s note verifies against it. Verifying a signature made by an unknown key only proves that unknown key signed the note. It does not bootstrap identity.
Where people get the fingerprint wrong
They copy it from the same HTML that contains the onion list. They compare four groups and skip the rest. They trust a key because the user id says “admin.” User ids are labels. Anyone can set them.
Keep a local record of fingerprints you have already checked. When an operator announces a rotation, the old key should sign the new fingerprint. If the new key just appears, unsigned by anything you already hold, that is a substitution until proven otherwise.
Timestamps: a good signature on dead text
OpenPGP signatures carry a creation time in the hashed data. GnuPG prints it as something like “Signature made” plus a date. That date is part of what you are verifying. Ignore it and you will accept a perfectly valid signature on an advisory from last year.
Replay is the boring attack. An old signed mirror list is still cryptographically genuine. The onions on it may now point at a seizure banner, a phishing clone, or a dead host. The signature does not expire just because the operational picture changed. Some signers set an expiration on the signature itself. Many do not. You have to read the clock.
Check three times, not one:
| Torzon Market |
torzon7aphar3x4l5b77nsylgyw26kntbi4m2wemrjh72aczeh27f6qd.onion
|
| Omega Market |
omega7yhz7n4vg4yhf2na2qaaaeatdlqvjbj2juc245mr5muxtnuvgyd.onion
|
| BlackOps |
blackoogcnxogvymmebfwfjhx4k7efpgeoeytxtsev2lc4pqlbz54qad.onion
|
| Vortex |
bar47kfsex6pvvs3iujqeo4fsnxxn67k7usc5jnbdnoozt3gnp4br7yd.onion
|
| Thor |
vck75uosucwzxgyp6yofroujgtasyuubkem7jh65r5ha5fmb6ztv6qqd.onion
|
- The signature creation timestamp versus the date the advisory claims to have been published.
- Whether your own clock is sane. A wrong system time makes you misread “made today” versus “made in 2022.”
- Whether the signed body includes a date, a serial, or a canary window you can match against previous notes.
A mismatch of hours can be timezone display. A mismatch of months is not. I have no patience for “the signature is good so the links are good” when the signature is older than the last known rotation. Signed does not mean fresh.
Also remember: a signer who controls their machine can set the clock when they sign. A forged timestamp is possible if the private key is in the attacker’s hands. Timestamp checks catch recycled old messages. They do not catch a live attacker with the current key. That is what revocation and canaries are for.
Revocation notices: the part most keyrings never see
A revocation is a special signature over a key that says stop using this. Once you import it, GnuPG will mark the key revoked and refuse to treat it as a valid signer for new trust decisions. If you never fetch the revocation, your local copy keeps looking healthy. That is how people keep verifying “admin” messages after the key was burned.
Revocation certificates are usually generated at key creation and stored offline. The holder publishes one when a key is compromised, superseded, or retired. Reasons are encoded in the packet (compromised, superseded, retired, no reason given). “No reason given” is common and unhelpful. “Key compromised” should make you treat every recent signature as suspect, not just future ones.
The ugly case is the one operators hate to admit. If they lost the private key and never generated a revocation cert in advance, they cannot revoke. They can only tell you in prose to stop using the fingerprint. Prose is not a revocation. Anyone still holding the private key can keep signing “we are fine” notes that verify on your machine. At that point the only defense is a prior fingerprint list plus a second, still-valid key (or an entirely new identity you authenticate the hard way).
When you see a revocation notice in an advisory, do the mechanical work:
- Import the revocation into the same keyring you use for verification.
- Run gpg –list-keys and confirm the key shows as revoked, not just that a text file mentioned it.
- Check whether signatures you already accepted were made before or after the revocation time.
- If a replacement fingerprint is included, authenticate that fingerprint independently. The revoked key signing its successor is useful. A random new block in the same paste is not.
Do not “update” your key by replacing a file in a folder and calling it done. If the old key still verifies in your tool, you did not apply the revocation.
Canaries, continuity, and what signatures cannot fix
Some communities publish PGP-signed canary messages at regular intervals. The point is negative evidence: a canary that fails to appear on schedule is a warning that the signer may no longer be in control, or chose to stop. A canary that does appear, with a fresh timestamp and a still-unrevoked key, is evidence of continued control of that key. It is not evidence that the people behind it are honest, solvent, or uncompromised in every other way.
Identity continuity across accounts works the same way. A user who signs with the same key over months is probably the same holder of that key. That is all. It does not make their claims true.
Directories that sign onion lists are doing the right cryptographic thing. You still should not treat a single signed page as a single point of failure in reverse. If the only place you ever saw the fingerprint is that directory, a full compromise of the host can replace both the list and the key you were going to check against. Out-of-band fingerprints, older signed notes you archived yourself, and independent copies of the public key are how you notice the swap.
One more limit, because people skip it. Never use a link from an advisory for a financial transaction without verifying the PGP signature on that advisory. And verifying means the full chain above, not a glance. Surface-web mirrors of those directories give your ISP a clear view of the visit. They also give you a document that is easier to tamper with than an onion you already authenticated. Use them, if at all, only as a pointer to a signed artifact you then check locally.
A working order of operations
I run advisories in this order. Skip a step and the rest is theater.
- Confirm you are verifying the exact bytes that were signed. Reformatting, extra whitespace, or a copy that lost the header will fail or, worse, you will verify a different file than the one you read.
- Show the full fingerprint of the verifying key. Compare it to your pinned copy. If you have no pinned copy, you are not verifying an operator. You are verifying a stranger.
- Read the signature timestamp. Reject silent replays. Demand a reason for any gap between claimed publication and signature time.
- Check the key’s own expiry and revocation status on your keyring, not in the HTML.
- If the body announces a rotation or a compromise, treat every signature after the last good canary as untrusted until the new fingerprint is pinned the same way the old one was.
Tools will lie to you in small ways. They wrap lines. They localize dates. They truncate fingerprints in the status line and print the full one only if you ask. Read the verbose output once per key, not once per year.
The failure mode I still see most is not a broken algorithm. It is a researcher who imported a key from the same page they are trying to authenticate, saw “Good signature,” and stopped. Signing is a wax stamp. The stamp is useless if you never learned what the real seal looks like, never checked when it was pressed, and never asked whether that seal was reported stolen.