Digital Signatures for Files: Prove Authenticity & Origin
Learn how digital signatures verify file authenticity and prevent tampering. Ensure recipients know who sent the file and that it hasn't been altered.
A digital signature is a cryptographic proof that a specific person or entity created a file and that the file hasn't changed since. Technically, you hash the file with SHA-256, then "sign" the hash with your private key using RSA-PSS, ECDSA, or Ed25519. Anyone with your public key can verify the signature — if it checks out, they know you authored the file and it's byte-identical to what you signed. Signatures are what macOS uses to verify app updates, what Git uses for commit authorship (git commit -S), and what PGP uses for signed emails. They solve a problem that encryption alone can't: proving who sent what.
Signatures vs. encryption: different jobs
Encryption keeps contents secret. Signatures prove authorship and integrity. They're complementary, not alternatives.
- Encrypt only: recipient knows the content but not who sent it. Anyone with the public key could have encrypted it.
- Sign only: recipient knows who sent it and that it wasn't tampered with, but the content is visible to anyone intercepting.
- Sign and encrypt: full authenticity, integrity, and confidentiality. PGP's default mode.
File transfer services typically focus on encryption. Signatures come into play for high-trust contexts: software distribution, legal documents, contracts, forensic evidence chains.
How signing actually works
The canonical Ed25519 signing flow:
- Hash the message:
h = SHA-512(message). - Compute a deterministic nonce:
r = SHA-512(private_key_prefix || h). - Compute the signature point:
R = r·G(where G is the curve's base point). - Compute
s = r + SHA-512(R || public_key || h)·private_key mod ℓ. - Signature is
(R, s), 64 bytes total.
Verification uses only the public key, the message, and the signature. If the math works out, the verifier knows the signature was produced by someone holding the matching private key.
RSA-PSS (PKCS#1 v2.2) and ECDSA work similarly but with different underlying math. Ed25519 is preferred for new systems because it's deterministic (no per-signature random nonce to go wrong) and faster.
The three common signature algorithms
| Algorithm | Key size | Signature size | Speed | Notes | |-----------|----------|----------------|-------|-------| | RSA-PSS-2048 | 256 bytes | 256 bytes | ~1000 sign/s | Widely supported, slow key generation | | ECDSA P-256 | 32 bytes | 64 bytes | ~30,000 sign/s | NIST curve, needs secure RNG per signature | | Ed25519 | 32 bytes | 64 bytes | ~50,000 sign/s | Deterministic, modern default |
All three are approved in NIST's FIPS 186-5 (2023). Ed25519 is the choice for new protocols: WireGuard, SSH (default since OpenSSH 8.0), Signal, Git commit signing, and Rust's Cargo package signing.
Code signing: a $100 billion use case
Software distribution relies on signatures. Without them, users can't distinguish the real installer from malware:
- Apple Developer ID + Notarization. All macOS apps must be signed and notarized since Catalina (2019). Uses RSA-2048 or ECDSA P-256.
- Microsoft Authenticode. Windows executables signed with RSA-3072 or ECDSA P-384 certificates.
- Android APK v2/v3. Ed25519 signatures over APK contents.
- Debian apt, Red Hat dnf, npm, PyPI, Homebrew. All use detached signatures (typically GPG Ed25519 or RSA) over package manifests.
A famous incident: in 2020, SolarWinds' Orion update was signed with the company's legitimate certificate after attackers compromised the build system. The signature was valid — it just proved the code came from a compromised source. Signatures guarantee the signer's identity, not the signer's judgment.
PGP and detached signatures for files
GnuPG (gpg) is still the workhorse for file signatures outside corporate PKI. A detached signature keeps the file unmodified and puts the signature in a separate .sig file:
gpg --detach-sign --armor document.pdf
# Produces document.pdf.sig
gpg --verify document.pdf.sig document.pdf
# gpg: Good signature from "Alice <alice@example.com>"
PGP's weakness is key distribution: how does the verifier know the signing key really belongs to Alice? Options include keyservers, web of trust, keybase.io, or out-of-band verification (published fingerprint on a business card).
Modern alternatives: Sigstore (used by Kubernetes, npm) does keyless signing using OIDC identity tokens, with transparency logs replacing the web of trust. minisign by Frank Denis offers simple Ed25519 signing without PGP's complexity.
Hash-based signature aggregation
For collections of files, signing each one individually is inefficient. Better: hash each file, build a Merkle tree, sign the root. Advantages:
- One signature covers many files.
- Individual files can be verified against the root with log(n) sibling hashes.
- Used by certificate transparency logs, Git, and increasingly by software supply chain tools like in-toto.
A 10,000-file release signed this way produces one signature plus a 32-byte root hash, verifiable against any subset of the files.
Timestamping: proving when
A signature proves who, but not when. An attacker who steals your private key can backdate signatures. Trusted Timestamping Authorities (TSAs) solve this by signing a timestamp over your signature, anchoring it to a specific moment.
Standards:
- RFC 3161 timestamping — used by Microsoft Authenticode, Adobe PDF signatures.
- RFC 5544 (CMS with timestamps).
- Roughtime — a newer protocol by Google for low-latency verified time.
Legal document signing (DocuSign, Adobe Sign, EU eIDAS qualified signatures) relies on RFC 3161 timestamps from trusted authorities to establish when a contract was signed.
Signatures in file transfer
Most consumer-facing file transfer services don't expose signatures directly — the AES-GCM authentication tag proves integrity within the transfer, and TLS proves the server's identity, but there's no built-in way to prove the sender's identity.
For high-trust transfers, signing happens before upload:
- Sender signs the file with Ed25519 or PGP, producing
file.extandfile.ext.sig. - Both files are uploaded to any transfer service (HexaTransfer, SwissTransfer, WeTransfer).
- Recipient downloads both, verifies the signature with the sender's public key.
This decouples authenticity from the transfer mechanism — the transfer service could be compromised without breaking the signature's validity, as long as the sender's private key stays secret and the recipient has the correct public key.
EU eIDAS qualified signatures
The European Union's eIDAS Regulation (EU 910/2014, revised 2024 as eIDAS 2.0) defines three signature tiers:
- Electronic signature — basic, includes scanned handwritten signatures.
- Advanced electronic signature (AES/AdES) — linked to the signer, detects tampering. PGP signatures qualify.
- Qualified electronic signature (QES) — AdES plus a qualified certificate from a Trust Service Provider, stored on a Qualified Signature Creation Device (smart card or HSM).
QES has the same legal weight as a handwritten signature across all EU member states. Providers include DocuSign EU, Adobe Sign EU, Namirial, and DTrust. US equivalents under ESIGN Act and UETA are less formally tiered but functionally comparable.
When signatures are overkill
Not every file needs a signature. Skip it when:
- The recipient trusts the transfer channel end-to-end (Signal, in-person USB).
- The content isn't security-critical (meeting photos, recipes, draft documents).
- Integrity alone is enough and provided by AES-GCM or TLS.
Add signatures when:
- Legal or contractual weight matters (contracts, court evidence, medical records).
- Supply chain trust is in play (software releases, firmware updates).
- The file will be forwarded through untrusted intermediaries.
- You need a durable audit trail that survives the original transfer.
Putting it to use
For a simple workflow: generate an Ed25519 key with ssh-keygen -t ed25519 -f ~/.ssh/signing_key, sign a file with openssl pkeyutl -sign -inkey signing_key -in file -out file.sig, share your public key out of band, and ship the file via any secure transfer service. Recipients verify with openssl pkeyutl -verify.
Try it at hexatransfer.com — free, no account, 10 GB max.
Send large files securely with end-to-end encryption
Transfer files up to 10 GB for free with end-to-end encryption. No account required. Your files are encrypted in your browser before upload — no one else can read them.
Send a file