Signing and Verifying Files in Practice
You have decided that some of your file transfers need signatures — proof of who produced a file and that it arrived unchanged. Now comes the part that trips people up: actually doing it, and doing the verification correctly rather than just eyeballing a green checkmark. The mechanics are not hard, but a few small decisions separate a signature that would hold up under scrutiny from one that quietly proves nothing.
This article is the hands-on companion to the concepts. If you have not read digital signatures explained with files, skim it first — here we assume you already know that signing uses your private key and verifying uses the public one. By the end you will be able to create a detached signature, verify a file a partner sent you, read what the verification tool is actually telling you, make the all-important trust decision about whose key you hold, and wire signing into routine transfers. This is part of our Signatures & Receipts series. The commands use OpenPGP tooling, the common choice for signing files that cross between organizations.
Detached vs Inline Signatures
Signatures come in a few shapes, and picking the right one for file transfer avoids a lot of grief.
An inline signature wraps the signature and the content together into a single new file. A clear-signed message does something similar for text, sandwiching the readable text between signature markers. Both change what the file looks like — the recipient now has a combined blob, not the original file.
A detached signature is the one you almost always want for transfers. It is a separate, small file — the signature only — that sits next to the untouched data file. If report.csv is your data, its detached signature is a sidecar named report.csv.asc or report.csv.sig. The data file is bit-for-bit unchanged, so every downstream system that expects a plain CSV still gets a plain CSV, and the proof simply travels alongside.
Why detached wins for transfers: the data file stays exactly as it was, so signing does not break the parser, loader, or partner system waiting at the other end. The signature is just one more small file in the batch. Reserve inline and clear-signed formats for cases where you specifically want the proof welded into the content, such as a short human-readable notice.
One-Time Setup: Your Key and Your Partner's Key
Before signing or verifying anything you need two things in place: your own key pair (to sign), and your partner's public key imported and confirmed (to verify what they send). Generating and storing your own key pair is its own topic — our pillar on encryption at rest and PGP covers key generation and hygiene — so here we focus on the partner side, because that is where verification lives or dies.
When a partner gives you their public key, import it and read its fingerprint — a short hash of the key itself that acts as its unique, human-comparable identity:
# Import a partner's public key file into your keyring gpg --import partner-public.asc # Show the key and print its full fingerprint gpg --fingerprint partner@partner.example
The fingerprint is the number you must confirm through a separate, trusted channel — a phone call to a known number, an in-person exchange, a value printed in a signed contract. Do not confirm it using the same email or server that delivered the key, because if that channel were compromised the attacker would happily confirm their own fake key. This out-of-band check is the single most important habit in this whole article, and we return to it below.
Imported keys live in your keyring — the local store your tool keeps of every public key you hold. As you onboard more partners the ring fills with their keys, so give each one a clear identity and keep your own note of which fingerprint you confirmed and when. A tidy keyring is not cosmetic. At verification time the tool automatically picks whichever key in the ring matches the signature, so a stale, duplicate, or never-confirmed key is exactly how a misleading "Good signature" sneaks through. Prune keys you no longer use, and re-confirm a partner's fingerprint whenever they send a new key rather than assuming the newcomer is as trustworthy as the one it replaces.
Creating a Detached Signature
With your own key in place, signing a file is one command. This produces an ASCII-armored (plain-text) detached signature next to the original:
# Sign report.csv with your key, producing report.csv.asc gpg --local-user you@example.com --armor --detach-sign report.csv # The data file is untouched; you now have two files to send: # report.csv <- the original data, unchanged # report.csv.asc <- the detached signature (the proof)
A note on the options, so none of it is magic. --local-user (short form -u) chooses which of your keys signs, which matters once you hold more than one. --armor makes the signature printable text ending in .asc rather than raw binary — friendlier to email and to systems that mangle binary. --detach-sign is the part that says "signature only, in its own file." Send both files together, and tell your partner which order you did things in if you also compress or encrypt (more on that under common mistakes).
Verifying a File a Partner Sent
This is the move you will make most often, because you receive more than you send. You have the data file, its detached signature, and the partner's public key already imported and fingerprint-confirmed. One command checks it:
# Verify the data file against its detached signature gpg --verify report.csv.asc report.csv
Order matters in the reading, not the typing: you name the signature file first and the data file second. The tool hashes report.csv, checks that hash against the signature using the partner's public key, and prints a verdict. Now you have to read that verdict properly — which is where most of the value is.
Reading the Verification Output
A successful check looks roughly like this (details vary by tool and key type):
gpg: Signature made <timestamp> using RSA key 3AA5B1C9D4E7F002 gpg: Good signature from "Partner Intake <partner@partner.example>" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner.
That output surprises people: it says Good signature and WARNING in the same breath. Both are true, and they mean different things. "Good signature" is the math: the file is unchanged and was signed by the private key matching this public key. The warning is about trust: your tool has no record that you ever confirmed this key really belongs to the partner. The math can be perfect while the key is an impostor's — exactly the gap the fingerprint check closes. Here is how to read each outcome:
| What the tool reports | What it actually means | What to do |
|---|---|---|
| Good signature, key certified/trusted | File intact and signed by a key you have confirmed belongs to the partner | Proceed |
| Good signature + "not certified" warning | Math is fine, but you have never confirmed this key is really the partner's | Confirm the fingerprint out of band, then proceed |
| BAD signature | The file changed, or it was not signed by this key | Stop; do not use the file; investigate and re-request it |
| Can't check / no public key | You don't hold the signer's public key at all | Obtain and fingerprint-confirm their key first |
The one line that should stop you cold is BAD signature. It is not a warning to click past; it means the bytes in front of you are not the bytes that were signed, or the key is wrong. Treat the file as untrusted until you understand why.
The Trust Decision: Whose Key Is This, Really?
Everything in this article rests on one decision that the software cannot make for you: do you believe this public key belongs to the party you think it does? A signature check answers "was this signed by the key?" It cannot answer "is the key genuinely my partner's?" Only you can, by confirming the fingerprint through a channel an attacker would not also control.
In practice that looks like: your partner sends their public key by email; you import it; you telephone their known number and read the fingerprint to each other, group by group, until every character matches; only then do you mark the key as confirmed in your notes and your tool. From that point on, a good signature from that key means something. Skip this step and you have built an impressive-looking process on sand — a forged file signed by an impostor's key will show "Good signature" just as cheerfully as the real thing.
Keep a small record of which key fingerprint you confirmed for which partner, when, and how. When a key expires or a partner rotates to a new one, you repeat the out-of-band confirmation for the new fingerprint rather than trusting the new key just because it arrived on the same thread as the old one.
Signing a Batch: One Signature for Many Files
Signing files one at a time is fine for a handful, but nightly jobs often move hundreds. Producing and shipping a separate .asc for every file works, yet there is a tidier pattern borrowed from integrity checking: sign a manifest.
A manifest is a plain-text list of every file in the batch alongside its hash — the same kind of checksum file described in our pillar on file integrity verification. You generate the manifest, then create one detached signature over the manifest itself. The partner verifies that single signature to trust the manifest, then checks each file's hash against the list. If every hash matches and the manifest signature is good, the whole batch is accounted for with one signing operation and one trust decision.
The payoff is more than convenience. A per-file signature proves each file individually, but a signed manifest also proves the set: a missing or added file shows up as a mismatch against the list. For batches where completeness matters as much as content — a day's invoices, a full export — signing the manifest captures "these files, all of them, exactly these bytes" in a way scattered per-file signatures do not.
Wiring Signing Into Routine Workflows
Signing by hand is fine for the occasional file, but the real payoff comes when it happens automatically on every transfer, with no one remembering to do it. The pattern is the same as manual signing, moved into the pipeline:
- Sign on the way out. As part of the job that prepares a file for sending, sign it and emit the
.ascsidecar, then transfer both files together. The proof is generated at the moment of departure, not reconstructed later. - Verify on arrival. As part of the job that picks up an inbound file, verify its signature before anything downstream touches it. A failed check should stop the pipeline loudly — move the file to a hold area and alert a human — rather than letting an unverified or tampered file flow onward.
- Use consistent names. Agree with each partner that the signature is always the data file name plus
.asc. Predictable naming is what lets an unattended job find the right signature for the right file every time. - Branch on the exit code, not the printed text. Verification tools signal success or failure with an exit status — zero for a good signature, non-zero for bad or unverifiable. Scripts should test that status to decide whether to proceed or divert to the hold area, rather than trying to parse the human-readable message, which can change between tool versions.
A scheduled-transfer client such as Sysax FTP Automation, which includes OpenPGP support, can fold the signing and verification steps into the same unattended job that moves the files, so signatures are produced and checked consistently on every run instead of depending on someone's memory at 2 a.m. Whatever tool you use, the principle holds: automated signing is only as trustworthy as the private key behind it, so protect that key as carefully as you would any password that guards money.
Common Mistakes That Waste a Signature
A signature that verifies against the wrong assumptions is worse than none, because it looks like assurance. The usual traps:
- Never confirming the fingerprint. The number one mistake: treating "Good signature" as trust when the "not certified" warning was there the whole time. Confirm the key out of band, once, and record it.
- Signing at the wrong stage. If you both sign and compress or encrypt, agree on the order. Signing the original and then encrypting is different from signing the encrypted blob, and the verifier must reproduce the same order or the check fails.
- Line-ending changes on text files. Moving a text file between systems can silently rewrite line endings, which changes the bytes and breaks the signature. Transfer in binary mode, or agree on a canonical form, so the file the partner verifies is byte-identical to the one you signed.
- Verifying against the wrong file. A detached signature only matches the exact data it was made for. Renaming or regenerating the data file after signing, then verifying, produces a puzzling BAD result. Keep the signed file and its signature paired.
- Ignoring key expiry. Keys can carry an expiry date. A signature made with a since-expired key, or verification against an expired key, needs judgment — note it and confirm the partner's current key rather than waving it through.
Logging the verification result matters too. When your server records that an inbound file was verified against a named key and passed, that log line becomes part of the evidence trail if the transfer is ever questioned. A server that keeps detailed activity logs, such as Sysax Multi Server, gives you that record as a matter of course, which the series article on building an evidence pack puts to work.
Putting It Together
Signing and verifying files is a short list of habits done consistently: prefer detached signatures so data files stay untouched; import each partner's public key and confirm its fingerprint out of band before you trust anything it signs; verify every inbound file and actually read the verdict, treating a BAD signature as a full stop; and where files move on a schedule, let automation sign on the way out and verify on the way in. Do those, and the green checkmark finally means what people assume it means.
From here, non-repudiation for business explains how much these signatures are worth when a partner disputes a transfer, and proof-of-delivery patterns outside AS2 shows how a signed acknowledgment turns into proof that a file was received.
Frequently Asked Questions
What is a detached signature, and why is it best for transfers?
My tool says "Good signature" but also warns the key is not certified. Is that safe?
What should I do if verification reports a BAD signature?
Why does verifying fail after I moved a text file between Windows and Linux?
Do I need the partner's private key to verify their file?
Can signing happen automatically in a scheduled transfer?
From the Sysax team: we build secure file transfer software for Windows — Sysax Multi Server, an FTP, FTPS, SFTP, and HTTPS server, and Sysax FTP Automation for scheduled, scripted transfers. Free trials are on the download page.
