Il medico o il coordinatore firma un documento PDF del FASAS appoggiando la propria Carta d’Identità Elettronica al lettore NFC del computer. Il risultato è un PDF firmato in formato PAdES, archiviato come nuova versione del documento, verificabile dentro e fuori dal FASAS.
Stato al 29/10/2026. Server, interfaccia web e FASAS Signer per computer sono completi e provati con un modulo PKCS#11 reale (SoftHSM2) e con certificati di prova. Nessuna piattaforma è stata ancora collaudata con una CIE reale: finché il collaudo non è fatto, la firma con CIE non va usata sui documenti degli ospiti. Le app per telefono sono prototipi (vedi più avanti).
legal_level = fea) e così la mostra nel documento e nelle impostazioni.| Obbligo | Nel FASAS | Resta da fare alla comunità |
|---|---|---|
| Identificare con certezza il firmatario | certificato della CIE verificato fino alle CA della CIE; codice fiscale uguale al profilo | — |
| Informarlo su condizioni e limiti d’uso; attivazione solo dopo la sua accettazione | prima della prima firma il firmatario legge e firma con la CIE la dichiarazione di accettazione; senza accettazione valida la firma dei documenti è bloccata | far approvare il testo dal legale e indicarlo in FASAS_FEA_TERMS_FILE (finché manca, il testo è marcato «bozza») |
| Conservare almeno 20 anni la dichiarazione e il documento di riconoscimento | dichiarazione firmata cifrata e certificato della CIE, con data di fine conservazione; non cancellabile, solo revocabile; inclusa nei backup | — |
| Darne copia gratuita al firmatario | «Scarica la tua copia» in Firma digitale; registro per l’amministratore | — |
| Rendere note le caratteristiche del sistema e delle tecnologie | pagina pubblica /firma/caratteristiche-firma-cie/ (nessun accesso richiesto) |
collegarla dal sito della comunità |
| Assicurazione di responsabilità civile di almeno 500.000 € (comma 2) | — | stipularla (chi la richiede e per quale soggetto: da verificare con il legale) |
| Modalità nel FASAS | Valore giuridico | Dove resta la chiave |
|---|---|---|
| Firma con CIE | Firma elettronica avanzata | nel chip della CIE |
| Firma remota del prestatore (QTSP) | Qualificata solo se il certificato lo dichiara (QcCompliance + QcSSCD) e la catena è verificata | nel dispositivo sicuro del prestatore |
| Certificato personale (.p12) | Non qualificata | in un file cifrato sul server |
| Approvazioni interne (SOS, chiusura turno, PAI) | Non è una firma elettronica avanzata né qualificata | nessuna chiave: utente e ora nell’audit |
Browser del medico (FASAS) Server FASAS Computer con lettore NFC
─────────────────────────── ──────────────────────── ──────────────────────────────
Anteprima completa del PDF
«Avvia la firma con CIE» ───────► richiesta: versione bloccata,
codice di controllo, scadenza
(5 min), nonce ◄── FASAS Signer chiede (in uscita,
HTTPS) le richieste in attesa
«In attesa della CIE» mostra titolo, versione, impronta e
CODICE DI CONTROLLO → «Firma con CIE»
«Carta rilevata» riceve il certificato ◄── legge il certificato (senza PIN)
· CF = CF dell'utente?
· CA della CIE? revoca?
· prepara il PDF (pyHanko) ───► attributi firmati + DigestInfo
«Autorizzazione richiesta» PIN digitato QUI (ultime 4 cifre)
«Firma in corso» la carta firma (PKCS#11, Software CIE)
«Verifica della firma» verifica RSA del valore, ◄── solo il valore di firma
inserisce la busta CMS, verifica
integrità/copertura/catena
«Documento firmato correttamente» nuova versione firmata + audit
CKM_SHA256_RSA_PKCS, oppure CKM_RSA_PKCS sul DigestInfo). Abbiamo verificato
nel sorgente ufficiale del middleware (repository italia/cie-middleware-*, licenza BSD-3) che in entrambi i
casi la carta riceve il DigestInfo SHA-256 e applica da sé il padding PKCS#1 v1.5.K7QM-3HXZ)
compare sia nella pagina del FASAS sia nel Signer: si firma solo se coincidono.FirmaFASAS1, FirmaFASAS2, …): le firme
precedenti restano valide.FASAS_SIGNATURE_TSA_URL): PAdES-B-T. Senza TSA:
PAdES-B-B. Nessuna marca temporale fittizia.| Stato | Documento | Significato |
|---|---|---|
| In attesa della CIE | in attesa di firma (bloccato) | richiesta creata; il Signer deve prenderla in carico e la carta va appoggiata |
| Carta rilevata | in attesa di firma | certificato letto e in controllo |
| Autorizzazione richiesta | in attesa di firma | PDF preparato; il Signer chiede il PIN |
| Firma in corso | firma in corso | PIN verificato, la carta sta firmando |
| Verifica della firma | firma in corso | il server verifica e archivia |
| Documento firmato correttamente | firmato | nuova versione firmata archiviata |
| Firma non riuscita / Annullata / Scaduta | torna modificabile | motivo mostrato; «Riprova» crea una nuova richiesta (nuovo codice e nonce) |
| Rischio | Contromisura |
|---|---|
| Una pagina web pilota il Signer (CSRF, richieste cross-origin) | il Signer non apre porte sul computer: contatta lui il server in uscita |
| Furto del token del dispositivo | sul server solo l’impronta SHA-256; il token da solo non basta: servono la carta e il PIN; revoca immediata da Impostazioni o dall’amministratore (Sistema › Dispositivi di firma) |
| Ripetizione di una risposta (replay) | nonce diverso a ogni passo, accettato una volta sola; richieste che scadono; valore di firma accettato una sola volta |
| Accesso alle richieste altrui (IDOR) | ogni richiesta è visibile e utilizzabile solo dal firmatario e dal dispositivo che l’ha presa in carico; i tentativi diversi finiscono nell’audit |
| Carta di un’altra persona | confronto del codice fiscale del certificato con il profilo dell’utente |
| Certificato falso, scaduto o revocato | catena verso le CA della CIE configurate, date di validità, revoca (OCSP/CRL) quando raggiungibile |
| Documento cambiato durante la firma | versione bloccata, impronta controllata prima e dopo, PDF firmato = originale + revisione incrementale |
| Dati sanitari nei log | il server registra solo codici di esito; il dispositivo può riportare solo codici d’errore noti, mai testo libero; il Signer non scrive titoli, PIN o certificati nei log; il PDF preparato è cifrato e cancellato a fine richiesta |
| Connessione in chiaro | il Signer rifiuta HTTP verso server non locali; le API rispondono 403 senza HTTPS (salvo FASAS_CIE_ALLOW_HTTP in sviluppo) |
| Abbinamento indovinato | codice monouso di 8 caratteri, valido 10 minuti; dopo 10 tentativi falliti per IP l’abbinamento si blocca per 10 minuti |
| Database (Supabase) | le nuove tabelle ricevono automaticamente RLS e la revoca dei privilegi pubblici come tutte le altre |
| Manomissione dell’audit | catena di impronte SHA-256 e trigger append-only su PostgreSQL: le manomissioni si rilevano. Non è un registro legalmente immodificabile |
| Elemento | Dove | Costo |
|---|---|---|
| CIE del firmatario con PIN e PUK | – | – |
| Lettore NFC contactless (ISO 14443) compatibile con la CIE | un lettore per ogni postazione di firma | indicativamente 20–50 € l’uno (stima, da verificare con i fornitori) |
| Software CIE del Ministero dell’Interno | ogni computer di firma | gratuito |
| FASAS Signer | ogni computer di firma | gratuito (questo progetto) |
| Certificati delle CA della CIE | server FASAS | gratuiti |
| Marca temporale (facoltativa) | server FASAS | servizio a pagamento di un prestatore (già previsto in FIRMA_DIGITALE.md) |
| Firma del codice del Signer (consigliata) | distribuzione | Windows: certificato Authenticode (centinaia di €/anno); macOS: Apple Developer Program |
Nessun servizio a pagamento è stato attivato.
Variabili d’ambiente (vedi config/settings.py):
| Variabile | Valore |
|---|---|
FASAS_CIE_ENABLED |
1 (predefinito) |
FASAS_CIE_TRUST_ROOTS |
percorso di un file PEM con i certificati radice della CIE. Obbligatorio: senza, la firma con CIE non parte |
FASAS_CIE_INTERMEDIATES |
PEM con le CA intermedie, se non sono già nella firma |
FASAS_CIE_REVOCATION |
soft-fail (predefinito: verifica la revoca se OCSP/CRL sono raggiungibili), hard-fail (rifiuta se non verificabile), off (solo prove) |
FASAS_CIE_TIMESTAMP |
1: marca temporale se è configurata la TSA |
FASAS_CIE_REQUEST_MINUTES |
durata massima di una richiesta (5) |
FASAS_CIE_PAIRING_MINUTES |
validità del codice di abbinamento (10) |
Le CA della CIE si scaricano dal sito ufficiale della CIE (Ministero dell’Interno). Prima di configurarle confrontate le impronte con quelle pubblicate dal Ministero: sono il punto su cui si regge la verifica. Il server deve poter raggiungere i servizi OCSP/CRL indicati nei certificati per il controllo di revoca.
Permessi: «Firma con CIE» è concesso a medico e coordinatore (signatures.sign_with_cie); l’amministratore
può solo revocare i dispositivi (signatures.manage_signer_devices). Nel profilo di ogni firmatario va inserito
il codice fiscale.
CIEPKI.dll in System32), macOS (pacchetto con
/Library/ipzs/libcie-pkcs11.dylib, oppure «Software CIE» dal Mac App Store), Linux (pacchetto .deb/.rpm con
/usr/local/lib/libcie-pkcs11.so, più pcscd). Percorsi presi dai manuali ufficiali.PIN errato: il Signer lo richiede e la pagina mostra i tentativi rimasti quando il modulo li comunica; dopo 3 errori il PIN si blocca e va sbloccato con il PUK dall’app CIE ID.
La CIE ha solo il chip contactless: senza lettore NFC non si può usare dal computer. Per provare tutto il resto (pagine, stati, FASAS Signer, PIN, firma PAdES, verifica, archiviazione) c’è una carta di prova: una chiave software emessa da una CA marcata «SOLO PROVA – NON È UNA CIE».
DJANGO_DEBUG=1):
python manage.py fasas_carta_di_prova --utente medico (PIN predefinito 1234). Il comando aggiunge al file
.env le CA di prova; poi il FASAS va riavviato.--carta-di-prova seguito dal percorso del file .p12 (cartella .carta-di-prova), solo
verso un FASAS sullo stesso computer; la finestra mostra in rosso «CARTA DI PROVA».DJANGO_DEBUG non è attivo.python -m fasas_signer --usa-cie e togliere da .env le righe della carta di prova.Il browser non basta: Web NFC (Chrome su Android) legge solo etichette NDEF e non invia comandi ISO 7816 al chip della CIE; Safari e le PWA su iPhone non accedono all’NFC. Per firmare con il telefono serve l’app FASAS Signer, che usa l’NFC del telefono al posto del lettore e le stesse API del Signer per computer (PIN completo di 8 cifre).
| Android | iPhone | |
|---|---|---|
| Codice | Kotlin, NFC IsoDep, libreria IAS di PagoPA/IPZS (MIT) | SwiftUI, Core NFC, CieSDK di PagoPA (MIT) + patch per la firma |
| Compilazione | ✅ APK di prova compilato da GitHub (artifact fasas-signer-android-prova); APK definitivo con la chiave della struttura (sotto) |
✅ compila su macOS nella CI, senza firma |
| Installazione | dal FASAS: Impostazioni › App per il telefono (gratuito) | serve l’Apple Developer Program e TestFlight |
| Collaudo con una CIE reale | ✅ CIE + PIN FASAS (registrazione e lettura, 4/11/2026); ⬜ firma con il PIN della carta | ⬜ |
| Guida | mobile/android | mobile/ios |
Per la prova, avvia-telefono.bat avvia il FASAS raggiungibile dal telefono sulla stessa Wi-Fi e mostra
l’indirizzo da inserire nell’app; solo le versioni di prova delle app accettano HTTP, e solo verso la rete locale.
App Android (dal 4/11/2026). La lettura NFC resta accesa fino all’esito e ogni errore diventa un messaggio (prima la schermata poteva restare ferma su «Avvicina la CIE»); stessa sequenza dell’SDK ufficiale (riconoscimento della carta, controllo «extended APDU», canale sicuro e PIN); se la carta si sposta basta riappoggiarla, la richiesta riprende dal punto raggiunto. Nella schermata principale:
Per aggiornare l’APK di prova bisogna prima disinstallare quello vecchio (ogni compilazione ha una firma di prova diversa) e poi abbinare di nuovo il telefono.
Il personale non usa GitHub: scarica l’app dal FASAS (Impostazioni › App per il telefono, con un QR code da inquadrare) e l’app avvisa da sola quando c’è una versione nuova. Gli aggiornamenti si installano sopra la versione precedente solo se sono firmati sempre con la stessa chiave della struttura.
Una volta sola, la chiave della struttura (su un PC con Java; keytool è incluso):
keytool -genkeypair -v -keystore fasas-signer.jks -alias fasas -keyalg RSA -keysize 3072 -validity 10000 -dname "CN=FASAS Signer, O=Nome della struttura, C=IT"
Custodire il file e la password come le chiavi di cifratura (cassaforte e copia in un secondo luogo, SICUREZZA_FISICA_E_CONTINUITA.md): se si perde, nessun telefono potrà più aggiornare l’app (andrà disinstallata e riabbinata).
FASAS_ANDROID_KEYSTORE_B64 (il file in
base64: base64 -w0 fasas-signer.jks su Linux, [Convert]::ToBase64String([IO.File]::ReadAllBytes("fasas-signer.jks"))
in PowerShell), FASAS_KEYSTORE_PASSWORD, FASAS_KEY_ALIAS (fasas), FASAS_KEY_PASSWORD (di solito la stessa).fasas-signer-android
con l’APK definitivo (solo HTTPS, numero di versione che cresce a ogni compilazione). Il registro della
compilazione riporta l’impronta SHA-256 del certificato di firma: annotarla.Chi ha installato una versione di prova (firma diversa) la disinstalla una volta e installa quella definitiva; poi abbina di nuovo il telefono. La CIE registrata e il PIN FASAS restano validi.
In Configurazione generale la direzione può attivare «verifica con CIE per aprire, scaricare o modificare i documenti» (spenta per default). Con la verifica attiva, prima di mostrare o cambiare un documento dell’ospite (anche già firmato) il FASAS chiede di confermare l’identità con la CIE:
| Dove | Cosa serve |
|---|---|
| Pagina del documento, «Apri», «Scarica», modifica, nuova versione, verifica e firma | verifica per quel documento |
| Esportazione della cartella con i documenti allegati e suo download dall’archivio report | verifica per tutti i documenti dell’ospite |
Come funziona: la pagina «Verifica con CIE» crea una richiesta con un codice di controllo; l’app FASAS Signer sul telefono (o il Signer sul computer) la mostra, l’utente digita il PIN e appoggia la carta, che firma una sfida casuale del server (non il documento). Il server controlla che il certificato sia emesso dalle CA della CIE, sia valido e sia intestato all’utente collegato (codice fiscale del profilo), verifica la firma della sfida e apre il documento per il tempo scelto in configurazione (10 minuti per default). È un’autenticazione, non una firma del documento: non crea versioni né firme e resta nell’audit («Accesso ai documenti verificato con CIE»).
Prima di attivarla:
FASAS_CIE_ENABLED) con le CA della CIE configurate: senza, la configurazione rifiuta
l’attivazione;Le richieste di verifica non permettono di firmare documenti: chi non ha il permesso di firma con CIE può solo
verificarsi. Provato con carte di prova (fasas.tests.test_cie_documenti): accesso solo al documento verificato e
per il tempo previsto, anche ai documenti firmati; carta di un’altra persona o di una CA estranea rifiutata;
esportazione con i documenti bloccata; attivazione rifiutata senza CIE sul server.
In Configurazione generale › come ci si verifica la scelta predefinita è «CIE appoggiata al telefono + PIN FASAS»: la carta si appoggia sempre, ma al posto del PIN della carta (che molti non ricordano) si digita un PIN FASAS scelto dall’utente. Chi ricorda il PIN della carta può usare anche quello. Per firmare i documenti con la CIE serve ancora il PIN della carta: è la carta stessa a chiederlo prima di usare la chiave di firma.
Si usa il protocollo ufficiale del Ministero dell’Interno per i servizi senza PIN, basato sul NIS (Numero Identificativo per i Servizi): Manuale di integrazione per servizi basati sul NIS, SDK di riferimento italia/cie-nis-java-sdk (BSD-3), di cui l’app Android ripete gli stessi comandi verso la carta:
Da configurare, una volta: i certificati della CSCA italiana da https://csca-ita.interno.gov.it, sezione
«Certificates». Si scaricano i file CSCA05.cer (attuale) e i precedenti CSCA04, CSCA03, CSCA02, CSCA01,
CSCA00 (le CIE più vecchie sono firmate da quelli); non servono i «Link Certificates», la Master List né la CRL.
Si mettono, così come sono, nella cartella certificati-csca dentro la cartella del FASAS (sul server:
/opt/fasas/certificati-csca, poi sudo ./scripts/aggiorna_fasas.sh --solo-sicurezza per ricostruire il FASAS),
oppure si indica un’altra cartella in FASAS_CIE_CSCA. Poi:
python manage.py fasas_csca
mostra i certificati caricati con l’impronta SHA-1 scritta come sul sito: devono coincidere tutte. Senza certificati la configurazione rifiuta la scelta «CIE + PIN FASAS».
Impronta o volto al posto del PIN FASAS: non realizzati. I telefoni non permettono alle app di registrare impronte o volti propri (solo quelli del telefono, che non si vogliono usare); conservare impronte o volti del personale sarebbe un trattamento di dati biometrici (art. 9 GDPR) con forti limiti del Garante per i dipendenti. L’unica via hardware sono chiavi di sicurezza personali con lettore di impronte (FIDO2), circa 50-100 euro a persona.
Provato con carte di prova (CSCA, Document Signer, SOD e chiave della carta generati nei test): registrazione, PIN FASAS (anche troppo facile, errato con nuovo tentativo, blocco dopo 5), conferma solo da un altro amministratore, accesso al documento; rifiutati carta diversa da quella registrata, clone senza chiave privata, SOD di una CSCA estranea, stessa carta per due utenti. Provato con una CIE reale su un telefono Android (4/11/2026): registrazione della carta (SOD verificato con i certificati CSCA del Ministero, autenticazione interna) e lettura con il PIN FASAS. Resta da provare su altri modelli di telefono e di carta: ognuno fa la prova con la propria CIE alla registrazione.
Automatiche (python manage.py test fasas.tests.test_cie_signature fasas.tests.test_cie_signer_pkcs11):
CKM_RSA_PKCS sul DigestInfo);Manuali in questo ambiente (Linux, Xvfb): finestra del FASAS Signer con SoftHSM e pagina del FASAS in Chromium, dall’anteprima del PDF fino a «Documento firmato correttamente» passando per un PIN errato; flusso Android (Kotlin) contro il FASAS con chiave di prova: seconda firma valida sullo stesso PDF.
Non verificato: qualunque firma con una CIE reale; Software CIE reale su Windows, macOS e Linux; lettori NFC reali; app Android su un telefono; app iOS; revoca OCSP/CRL con i servizi reali della CIE; marca temporale reale.