The formats of the digital signature

A file called contract.pdf.p7m lands in your inbox and your computer has no idea what to do with it. Or a PDF that opens normally yet claims to be signed. Or an XML nobody explained to you. They are all digital signatures, and the reason they come in different shapes is simpler than it looks: the container depends on what you are signing.

What a digital signature actually signs

Before the formats, the mechanism. Signing does not mean encrypting the document. It means:

  1. computing the document's digest (typically SHA-256);
  2. transforming that digest with the signer's private key, which lives inside a smart card and never leaves it;
  3. attaching the result, together with the certificate binding that key to a name.

Anyone holding the certificate can run the computation backwards and check that the digest matches. The document stays in the clear. What is protected is not confidentiality: it is attribution and integrity.

Hence the first practical question: where do I put the signature? Inside the document, next to it, or around it? Those three answers generate the families of formats.

Attached and detached

An attached (or enveloping) signature swallows the document: the signed file contains both the original bytes and the signature. Out comes a single object, which must be «unwrapped» to read the document again. That is the classic .p7m.

A detached signature lives separately: the document stays as it was, and the signature is a file alongside it holding its digest. Convenient for enormous files you would rather not duplicate inside an envelope.

Then there is the middle way, the most elegant: the enveloped signature, embedded inside the document itself without altering its format. A signed PDF remains a PDF that opens in any reader. That is how PAdES works.

CAdES contract.pdf.p7m CMS / PKCS#7 envelope the document signature + certificate attached: the file contains the document PAdES contract.pdf the PDF, still a PDF /ByteRange /Contents = signature enveloped: opens in any PDF reader XAdES invoice.xml XML tree signed content ds:Signature enveloped: a node inside the XML itself JAdES token / payload header payload signature three parts, base64url JWS: born on the web, adopted by eIDAS Four containers, one mechanism: the document's digest, transformed with the private key, plus the certificate. The «AdES» suffix stands for Advanced Electronic Signature: these are the ETSI profiles of the European advanced signature. Probatio verifies all four.
The wrapper changes, the substance does not. Understand the mechanism and you will recognise formats you have never seen.

The formats, one by one

CAdES — the .p7m

It is the CMS envelope (Cryptographic Message Syntax, the successor to PKCS#7), encoded in DER, that is, a binary ASN.1 structure. The filename doubles its extension — contract.pdf.p7m — because the envelope contains a PDF, but it is not a PDF.

It is the format for signing anything at all: an image, a ZIP, an executable. It does not care what is inside. It is also the format in which Italian electronic invoices, transmitted as XML, are wrapped and signed.

PAdES — the signed PDF

The signature lives inside the PDF, in a dictionary with two decisive fields. /Contents holds the CMS envelope with the signature proper. /ByteRange declares which byte intervals of the file were signed — that is, the whole PDF except the space in which the signature itself is written, because data cannot contain its own digest.

The PDF still opens anywhere. And because the signature covers a precise byte interval, the document can be signed several times by different people, each appending a new section at the end: this is the incremental update, and it allows sequential signing without destroying earlier signatures.

XAdES — the signed XML

A ds:Signature node inside the XML tree. The technical difficulty here is not cryptography: it is that the same XML can be written in syntactically different but logically identical ways — whitespace, attribute order, namespace prefixes. Signing the digest of raw bytes would be desperately fragile.

Hence canonicalisation: a procedure that rewrites the XML into a normal form before its digest is computed. Probatio implements C14N 1.0 and Exclusive C14N, with the enveloped and XPath Filter 2.0 transforms. It is the format of the Italian tax-authority interchange receipts.

JAdES — the JSON signature

A JWS (JSON Web Signature): three dot-separated parts — header, payload and signature — each in base64url. It was born in the world of web tokens and adopted by the ETSI profiles for interoperability with APIs. Probatio verifies both the compact and the flattened-JSON serialisation.

The .tsr is not a signature

In the same folder you will often find a .tsr file. It signs no one: it is the reply of a time-stamping authority, an RFC 3161 token attesting when that digest existed. A different question and a different tool — and it deserves its own guide.

Summary

ExtensionFormatContainerThe document is…
.p7mCAdESCMS / PKCS#7 in DERinside the envelope (attached)
.pdfPAdESPDF dictionary with /ByteRangethe PDF itself (enveloped)
.xmlXAdESds:Signature nodethe XML itself (enveloped)
JWS tokenJAdESheader.payload.signaturethe payload
.tsrRFC 3161 tokennot a signature: it is a timestamp

How Probatio recognises the format

It does not trust the extension. It looks at the bytes.

the first bytes of the file %PDF signature inside the PDF a.b.c base64url three dot-separated parts ds:Signature a node inside an XML none of the above a CMS envelope is attempted PAdESJAdESXAdESCAdES on failure: format not recognised Renaming a .p7m to .pdf does not make it a PDF, and Probatio does not fall for it. The ASN.1 parser also accepts indefinite-length BER envelopes, converting them to DER before verification.
Order matters: a signed PDF contains a CMS envelope inside it, and without the initial %PDF check it would be mistaken for a CAdES.

Two things Probatio does not do

ASiC, the ZIP container that packages documents and signatures together (ASiC-S and ASiC-E), is not supported. If you receive an .asice, unpack it first.

Countersignatures — the CMS countersignature attribute, by which a second signer signs the first signer's signature — are not extracted. Among the unsigned attributes, Probatio reads timestamp tokens, not countersignatures.

What to take away

  • A .p7m is an envelope: your document is inside, and must be extracted to be read.
  • A signed PDF is still a PDF: it opens, it reads, and the signature covers the intervals declared in /ByteRange.
  • A .tsr is a timestamp, not a signature.
  • The extension is a hint, not a fact: the format lives in the bytes.
  • That a file is signed does not mean the signature is valid. That is the next question.