I formati della firma digitale

Ti è arrivato un file che si chiama contratto.pdf.p7m e il computer non sa cosa farne. Oppure un PDF che si apre normalmente ma dichiara di essere firmato. Oppure un XML che nessuno ti ha spiegato. Sono tutte firme digitali, e la ragione per cui hanno forme diverse è più semplice di quanto sembri: il contenitore dipende da cosa stai firmando.

Cosa firma, davvero, una firma digitale

Prima dei formati, il meccanismo. Firmare non significa cifrare il documento. Significa:

  1. calcolare l'impronta del documento (tipicamente SHA-256);
  2. trasformare quell'impronta con la chiave privata del firmatario, che vive dentro una smartcard e non ne esce mai;
  3. allegare il risultato, insieme al certificato che lega quella chiave a un nome e cognome.

Chiunque, con il certificato, può rifare il conto al contrario e verificare che l'impronta corrisponda. Il documento resta in chiaro. Ciò che è protetto non è la riservatezza: è l'attribuzione e l'integrità.

Da qui nasce la prima domanda pratica: dove metto la firma? Dentro il documento, accanto al documento, o attorno al documento? Le tre risposte generano le famiglie di formati.

Attached e detached

Una firma attached (o enveloping) inghiotte il documento: il file firmato contiene sia i byte originali sia la firma. Ne esce un unico oggetto, che va «scartato» per rileggere il documento. È il caso classico del .p7m.

Una firma detached vive separata: il documento resta com'era, e la firma è un file a fianco che ne contiene l'impronta. Comodo per file enormi, che non si vuole duplicare dentro una busta.

Poi c'è la via di mezzo, la più elegante: la firma enveloped, incorporata dentro il documento stesso senza alterarne il formato. Un PDF firmato resta un PDF che si apre con qualsiasi lettore. È così che funziona PAdES.

CAdES contratto.pdf.p7m busta CMS / PKCS#7 il documento firma + certificato attached: il file contiene il documento PAdES contratto.pdf il PDF, ancora un PDF /ByteRange /Contents = firma enveloped: si apre con qualsiasi lettore XAdES fattura.xml albero XML contenuto firmato ds:Signature enveloped: un nodo dentro l'XML stesso JAdES token / payload header payload signature tre parti, base64url JWS: nato per il web, adottato da eIDAS Quattro contenitori, un solo meccanismo: impronta del documento, trasformata con la chiave privata, più il certificato. Il suffisso «AdES» sta per Advanced Electronic Signature: sono i profili ETSI della firma avanzata europea. Probatio verifica tutti e quattro.
Cambia l'involucro, non la sostanza. Chi capisce il meccanismo riconosce i formati che non ha mai visto.

I formati, uno per uno

CAdES — il .p7m

È la busta CMS (Cryptographic Message Syntax, l'evoluzione di PKCS#7), codificata in DER, cioè in una struttura binaria ASN.1. Il nome del file raddoppia l'estensione — contratto.pdf.p7m — perché la busta contiene un PDF, ma lei non è un PDF.

È il formato per firmare qualsiasi cosa: un'immagine, uno ZIP, un eseguibile. Non gli interessa cosa c'è dentro. È anche il formato in cui vengono firmate le fatture elettroniche italiane trasmesse in XML dentro una busta .p7m.

PAdES — il PDF firmato

La firma è dentro il PDF, in un dizionario che contiene due campi decisivi. /Contents ospita la busta CMS con la firma vera e propria. /ByteRange dichiara quali intervalli di byte del file sono stati firmati — cioè tutto il PDF tranne lo spazio in cui la firma stessa è scritta, perché un dato non può contenere l'impronta di sé stesso.

Il PDF resta apribile ovunque. E poiché la firma copre un intervallo di byte preciso, il documento può essere firmato più volte da persone diverse, aggiungendo ogni volta una nuova sezione in coda: è l'incremental update, e permette la firma sequenziale senza distruggere le precedenti.

XAdES — l'XML firmato

Un nodo ds:Signature dentro l'albero XML. La difficoltà tecnica qui non è la crittografia: è che lo stesso XML può essere scritto in modi sintatticamente diversi ma logicamente identici — spazi, ordine degli attributi, prefissi di namespace. Firmare l'impronta dei byte grezzi sarebbe fragilissimo.

Per questo esiste la canonicalizzazione: una procedura che riscrive l'XML in una forma normale prima di calcolarne l'impronta. Probatio implementa la C14N 1.0 e la Exclusive C14N, con le trasformate enveloped e XPath Filter 2.0. È il formato delle ricevute del Sistema di Interscambio.

JAdES — la firma JSON

Un JWS (JSON Web Signature): tre parti separate da punti, header, payload e firma, ciascuna in base64url. Nasce nel mondo dei token web e viene adottato dai profili ETSI per l'interoperabilità con le API. Probatio ne verifica sia la forma compatta sia quella JSON flattened.

Il .tsr non è una firma

Nella stessa cartella, spesso, trovi un file .tsr. Non firma nessuno: è la risposta di un'autorità di marcatura temporale, un token RFC 3161 che attesta quando quell'impronta esisteva. È un'altra domanda e un altro strumento — e merita la sua guida.

Riepilogo

EstensioneFormatoContenitoreIl documento è…
.p7mCAdESCMS / PKCS#7 in DERdentro la busta (attached)
.pdfPAdESdizionario PDF con /ByteRangeil PDF stesso (enveloped)
.xmlXAdESnodo ds:Signaturel'XML stesso (enveloped)
token JWSJAdESheader.payload.firmail payload
.tsrtoken RFC 3161non è una firma: è una marca temporale

Come Probatio riconosce il formato

Non si fida dell'estensione. Guarda i byte.

i primi byte del file %PDF firma nel PDF a.b.c base64url tre parti separate da punti ds:Signature nodo dentro un XML nessuno dei precedenti si tenta la busta CMS PAdESJAdESXAdESCAdES se fallisce: formato non riconosciuto Rinominare un .p7m in .pdf non lo trasforma in un PDF, e Probatio non ci casca. Il parser ASN.1 accetta anche buste BER a lunghezza indefinita, convertendole in DER prima di verificarle.
L'ordine conta: un PDF firmato contiene una busta CMS al suo interno, e senza il controllo iniziale su %PDF verrebbe scambiato per un CAdES.

Due cose che Probatio non fa

ASiC, il contenitore ZIP che impacchetta documenti e firme insieme (ASiC-S e ASiC-E), non è supportato. Se ricevi un .asice, va scompattato prima.

Le controfirme — l'attributo CMS countersignature, con cui un secondo firmatario firma la firma del primo — non vengono estratte. Probatio legge, fra gli attributi non firmati, i token di marca temporale, non le controfirme.

Cosa portarsi a casa

  • Il .p7m è una busta: dentro c'è il tuo documento, e va estratto per leggerlo.
  • Un PDF firmato resta un PDF: si apre, si legge, e la firma copre gli intervalli dichiarati in /ByteRange.
  • Il .tsr è una marca temporale, non una firma.
  • L'estensione è un suggerimento, non un fatto: il formato sta nei byte.
  • Che il file sia firmato non significa che la firma sia valida. Quella è la domanda successiva.