Login
Cerca all'interno di JavaPortal
Help
Home Page Documentazione Forum Progetti Partner Pubblica!
Documentazione > Tutorial > Prototipo,in Java, di Applicazione per la Firma Digitale
Hide
Best Practices
EJB
Frameworks
Howto
J2EE
J2ME and Wireless
J2SE
JSP e Servlet
Java Application Server
Java IDE/Tools
Java Media
Java Security
Java Sys Admin
Java e XML
Java e SQL
OpenSource Java
Patterns
Repository
Tesi
UML
Web Services
Slide
White Paper di jws.it
project management
Eventi
Groovy

Hai una tesi in Java?
Tesine preparate
per esami?
Pubblica tutto su
JavaPortal!

Scrivi al nostro staff


Gruppo di studio Java su Second Life by Paideia.


Henry Ford
Vero progresso quando i vantaggi di una nuova tecnologia diventano per tutti


GRASP : Pattern Information Expert


Rss Feed
Home Page
Articoli
News
Forum
Classi

 
Add to Shortcuts
Prototipo,in Java, di Applicazione per la Firma Digitale

Università Degli Studi di Firenze

Facoltà di scienze Matematiche, Fisiche e Naturali

Prototipo di Applicazione per la Firma Digitale

Tesi di Iacopo Pecchi

E' possibile fare il download della Tesi in PDF

 

Sito web dell' autore:  http://www.iacopopecchi.it/

 

 

Indice

1 Introduzione
2 Crittografia
2.1 Crittografia
2.1.1 Servizi
2.1.2 Crittografia Simmetrica
2.1.3 Analisi Crittografica
2.1.4 Crittografia Asimmetrica
2.1.5 Dettagli
2.1.6 Algoritmo RSA
2.1.7 Funzioni HASH
3 Il mondo della Firma Digitale
3.1 Firma Digitale
3.1.1 Firma Digitale in dettaglio
3.2 Certificati Digitali
3.2.1 Utilizzo dei Certificati
3.3 Gli altri aspetti della Firma Digitale
3.3.1 La difiusione della firma digitale in Europa
3.3.2 Il valore legale della firma digitale in Italia
3.3.3 Dove e come dotarsi di firma digitale
3.3.4 Il kit di firma digitale ed i costi
3.3.5 I cittadini
3.3.6 Le Imprese
3.3.7 Le pubbliche Amministrazioni
3.3.8 Lo strumento firma digitalefi integrato nel processo di e-government
4 Gli Standard Utilizzati
4.1 PKCS
4.1.1 PKCS#1
4.1.2 PKCS#7
4.1.3 PKCS#11
4.2 X.509: standard per i certificati
4.2.1 Struttura di un Certificato
4.2.2 Metodi di Veri_ca dei Certificati
4.2.3 CRL in dettaglio
4.3 MIME
4.4 S/MIME
5 Il Prototipo di Applicazione
5.1 L'applicazione
5.1.1 Le scelte ed il Contesto
5.1.2 Il linguaggio: JAVA
5.2 La smart card a supporto della crittografia
5.2.1 Le librerie utilizzate
5.3 I servizi e le funzionalità
5.3.1 Il punto di riferimento
5.4 Applet
5.4.1 L'applet per la Firma Digitale
5.4.2 La sicurezza nelle Applet
5.4.3 Il processo di creazione chiavi/certi_cato ed il processo di firma
5.4.4 Le politiche di sicurezza dell'applet di firma digitale
5.5 Multipiattaforma, Interoperabile e Compatibile
5.5.1 Rifiessione sul problema di Certificazione
5.6 Gli algoritmi di Firma e Verifica
5.6.1 Firma in generale
5.6.2 Il processo di Firma nella nostra Applet
5.6.3 Il processo di Verifica
6 Manuale Utente
6.1 Introduzione
6.2 Requisiti
6.3 Accedere all'Applet
6.3.1 La sicurezza
6.4 Selezionare ed Eliminare i Files
6.5 Firma
6.6 Verifica
Bibliografia

 

Capitolo 1

Introduzione

La diffusione di Internet ha reso ancor più impellente il bisogno di proteggere i dati disponibili in formato elettronico; è nata quindi l'esigenza di rendere privati e segreti i dati scambiati tra comunicanti remoti; con il passare del tempo e con la maturazione degli utenti della rete, ovvero con il diffondersi della fiducia nelle nuove tecnologie, alla segretezza dei dati si sono affiancati anche i termini di identità ed autenticità.

Internet si sta ormai facendo sempre più spazio nella nostra società ed è ormai visto non solamente come un mezzo di informazione, ma come uno strumento mirato al miglioramento delle nostre vite, alla semplificazione delle nostre radicate routine quotidiane; con il diffondersi delle operazioni commerciali sul Web è nata la necessità di certificare la nostra identità, assicurando l'interlocutore sulla corrispondenza tra chi siamo e chi dichiariamo di essere.

Lo strumento più semplice disponibile per questa operazione è la firma: strettamente personale, univoca e (almeno teoricamente) non riproducibile. Oggigiorno ci si propone di portare questo concetto nel mondo informatico creando un sistema che dia valore giuridico ai documenti elettronici. In questo modo le Pubbliche Amministrazioni potranno rendere disponibili procedure remote e semiautomatiche che consentiranno di ottenere tutto ciò che normalmente arriva solo dopo una visita all'ufficio, qualche ora di coda allo sportello e una discussione con il funzionario di turno. Lo stesso dicasi per tutti gli altri tipi di enti pubblici e privati i quali, avendo la possibilità di accertare l'identità dell'interlocutore, non tarderanno a predisporre la più ampia varietà di servizi telematici personalizzati.

Il mezzo che ci permette di rendere manifesta l'identità di una parte e di provare l'integrità dei dati scambiati nella rete è la Firma Digitale, un insieme di matematica applicata e leggi che grazie all'informatica riesce ad essere uno strumento che diverrà di fondamentale importanza per i cittadini nell'immediato futuro.

Il primo compito di questa è quindi spostare il dialogo ufficio-cittadino su reti come Internet, avendo come conseguenza l'azzeramento dei tempi di attesa, la possibilità di usufruire dei servizi continuati, l'immediato aggiornamento delle banche dati e per ultimo la possibilità, per i dipendenti degli uffici, di concentrarsi sulla qualità dei servizi.

Agendo in un panorama legislativo Italiano in campo di Firma Digitale che solamente adesso si sta stabilizzando con le varie direttive del Codice dell'Amministrazione Digitale in questa tesi si è sviluppato un prototipo di Applicazione per la Firma Digitale in grado di firmare documenti con l'utilizzo di dispositivi crittografici sicuri quali le smart card e di verificare la firma apposta sui file rispettando le politiche Italiane in merito, ovvero garantendo la compatibilità con i software rilasciati dai vari Certificatori Accreditati.

E' stata scelta la parola ``prototipo'' di applicazione in quanto questo progetto può essere considerato una ``macchina'' di prova, un programma disegnato per scopi dimostrativi.
Vi sono anche altri motivi legati all'utilizzo di questo termine ed essi sono tutti dovuti alle differenze che il progetto ha con l'applicazione Certificata e riconosciuta legalmente per la firma digitale qual'è l'applicazione FirmaOK!gold di Poste Italiane, differenze che la rendono per certi aspetti peggiore e migliore di quella di PosteCert (Poste in campo di Firma Digitale).
L'applicazione di Postecert è stata il modello funzionale sul quale si è basata la costruzione e lo sviluppo dell'applet sia dal punto di vista progettuale/implementativo che di usabilità.
Non si vuole però focalizzare l'attenzione su quale applicazione può essere la migliore, (anche perchè il prototipo sviluppato implementa solo alcune delle funzionalità disponibili in FirmaOK!gold), ma quali interessanti caratteristiche una applicazione di firma come FirmaOK!gold potrebbe introdurre/integrare per migliorare la portabilità e la interoperabilità con i vari dispositivi.

Tutto ciò solamente un primo passo in avanti verso il futuro della firma digitale, un mondo che per adesso è legato ad una ristretta classe di utilizzatori legati alle Pubbliche Amministrazioni, ma che a breve, con l'informazione sulle sue potenzialità, sulle sue sicurezze ed insicurezze potrà essere compreso ed utilizzato da tutti.

Capitolo 2

Crittografia

2.1 Crittografia

Prima di poter parlare di firma digitale e di tutti gli aspetti a questa correlati dobbiamo introdurre la Crittografia. Molte volte si è soliti usare questo termine come sinonimo di Crittologia.

Per Crittologia si intende la scienza delle scritture segrete; questa si divide in due branche:

  • Crittografia: arte di rendere segreti i messaggi ad un ``nemico''.
  • Crittanalisi: arte di decrittare i messaggi segreti.

La crittografia, per quanto moderna ed oscura per la società, ha delle antiche origini; questa infatti soddisfa il bisogno umano di rendere segreta o accessibile solo a chi di diritto una informazione o conoscenza.
Una prima forma di crittografia è stata la scrittura: pensiamo all'antica Cina; soltanto la classe sociale più elevata aveva il diritto di imparare a leggere e scrivere.
Si può risalire sino al 1900 A.C., dai geroglifici Egizi sino all'età di Giulio Cesare (50-60 A.C.) con il suo cifrario a sostituzione.

Da una parte la crittografia ha quindi alle sue spalle una lunga storia, fatta di Re, governi, società segrete e dall'altra è il nucleo del cyberspazio.
Questa infatti sta alla base del commercio elettronico e di tante altre cyber-attività/tecnologie che esistono solamente grazie ad essa.

2.1.1 Servizi

Prima di poter accennare agli attacchi ed alle minacce in cui possiamo incorrere nella rete, è necessario introdurre i ``servizi'' offerti dai vari tipi di protezione dei dati.

- Confidenzialità (o segretezza): garantisce che i dati siano accessibili solo alle parti autorizzate.
- Integrità: assicura che un messaggio venga trasmesso senza subire modifiche da parte di terzi non autorizzati.
- Autenticazione: assicura che l'origine di un messaggio sia correttamente identificata e che non sia stata falsificata.
- Non ripudiabilità: garantisce che ne' il mittente ne' il destinatario potranno negare di aver trasmesso o ricevuto un messaggio.
- Controllo degli accessi: assicura che l'accesso esterno ai dati sia in ogni momento ristretto ai soli autorizzati.
- Disponibilità: garantisce che il sistema sia disponibile agli autorizzati ogni qualvolta si renda necessario.

2.1.2 Crittografia Simmetrica

La crittografia a chiave simmetrica, detta anche crittografia convenzionale, è stata l'unica utilizzata prima della crittografia a chiave pubblica e rimane tutt'oggi la più comune forma di protezione dei dati. Prima di iniziare è opportuno definire alcuni termini.

Il messaggio originale è detto ``testo in chiaro'' mentre quello codificato è detto ``testo cifrato''. L'operazione di conversione da testo in chiaro a testo cifrato è detta ``crittografia'' mentre l'operazione inversa è chiamata ``decrittografia''.

Vediamo come funziona la crittografia a chiave simmetrica (o unica). Gli elementi base sono:

- testo in chiaro, è il messaggio originale oppure i dati che vengono inviati all'algoritmo

- algoritmo di crittografia, l'algoritmo che esegue la trasformazione del testo in chiaro

- chiave segreta, è un input dell'agoritmo di crittografia. La chiave è un valore indipendente dal testo in chiaro; l'algoritmo produce testi cifrati differenti a seconda della chiave utilizzata

- testo cifrato, testo a cui sono state applicate trasformazioni crittografiche; dipende dal testo in chiaro e dalla chiave segreta. Per un determinato testo in chiaro due chiavi differenti producono testi cifrati differenti. Il testo cifrato è un flusso apparentemente casuale di dati e non è comprensibile.

Vi sono alcuni presupposti che devono valere per la Crittografia a chiave simmetrica:

- l'algoritmo crittografico deve essere un algoritmo forte. Questo significa che un malintenzionato non può decifrare il testo cifrato conoscendo soltanto il tipo di algoritmo utilizzato ed avendo accesso ad uno o più testi cifrati.

- Il mittente ed il destinatario devono essere a conoscenza della chiave segreta che deve essere stata distribuita loro in modo sicuro; se qualcuno ne venisse a conoscenza le comunicazioni che utilizzano quella chiave risulterebbero leggibili.

Alla base della crittografia a chiave simmetrica vi è la chiave segreta ed il modo in cui questa viene distribuita e conservata.

Ecco uno schema di come la crittografia simmetrica funziona:

Come si può vedere l'algoritmo di cifratura applicato al testo in chiaro e alla chiave segreta produce un testo cifrato. L'ipotetico destinatario utilizza l'algoritmo con il testo cifrato e la chiave segreta come input; se la chiave è corretta ed il messaggio cifrato non è stato alterato l'algoritmo produce il testo in chiaro.

I sistemi crittografici si basano su tre dimensioni indipendenti:

1- Le operazioni utilizzate per trasformare il testo in chiaro in testo cifrato. Tutti gli algoritmi di crittografia si basano su due principi generali: la sostituzione, in cui ciascun elemento del testo in chiaro (bit o gruppo di bit) viene mappato su un altro elemento e la trasposizione, in cui gli elementi del testo in chiaro vengono cambiati di posizione. Il requisito fondamentale è che tutte le operazioni siano reversibili, perchè appunto la decrittografia sia possibile.

2-Numero di chiavi utilizzate (cifratura simmetrica e asimmetrica).

3-Modo di elaborazione del testo in chiaro, ovvero cifratura a blocchi e a flusso. La prima elabora il testo in chiaro un blocco alla volta producendo un blocco di output per ogni blocco di input. La seconda elabora il testo in chiaro in modo continuo finchè si presenta input.

2.1.3 Analisi Crittografica

La crittanalisi è quella parte della crittologia che si occupa di decifrare i messaggi segreti. Questa è una nobile arte che porta avanti lo sviluppo di sempre più potenti e resistenti algoritmi di cifratura, ma è anche il meccanismo che le parti malintenzionate utilizzano per attaccare i comuni schemi di crittografia.

Vi sono due principali attacchi alla crittografia a chiave unica (simmetrica):

- Analisi Crittografica: un attacco ad analisi crittografica si basa sulla natura dell'algoritmo e sfrutta qualche conoscenza delle caratteristiche generali del testo in chiaro o di qualche coppia di testo in chiaro/testo cifrato. Lo scopo è individuare il testo in chiaro o la chiave.

- Attacco a forza Bruta: in questo attacco vengono tentate tutte le possibili chiavi su di un frammento di testo in chiaro fino a che non si riesce ad ottenere una traduzione corretta. In media per avere successo si devono provare circa la metà delle chiavi.

2.1.4 Crittogra_a Asimmetrica

La crittografia asimmetrica risolve il problema dello scambio delle chiave condivisa presente nella simmetrica, che come è noto, è una operazione assai complessa senza un incontro faccia a faccia.
La crittografia a chiave pubblica è forse la più grande rivoluzione dell'intera storia della crittografia.
In questa non vengono più utilizzate le varie tecniche di sostituzione e permutazione ma delle funzioni matematiche. Questa ci permette di spedire messaggi in modo sicuro a persone che non abbiamo mai incontrato e con le quali non condividiamo nessuna chiave segreta.

Con un esempio reale ecco ciò che la crittografia a chiave pubblica permette di fare:
pensiamo a due amici che si trovano ai due angoli opposti di una stanza piena di matematici. I due amici si scambiano dei numeri gridando; quando hanno finito, entrambi conoscono lo stesso numero casuale e qualunque altra persona nella stanza ne è completamente all'oscuro.
Si! suona come impossibile, ma è realtà.

Tutto questo grazie a funzioni matematiche che sono facili da calcolare in un senso e difficili o computazionalmente impossibili nell'altro; la fattorizzazione di interi è una di queste: dati due numeri primi è facile calcolarne il prodotto, ma dato un prodotto, è molto difficile calcolarne i fattori primi dai quali deriva.

La crittografia a chiave pubblica interessa quindi l'aritmetica modulare, l'esponenziazione e grandi numeri primi di migliaia di cifre, ma questi sono i dettagli trascurabili per la comprensione della funzione della cifratura asimmetrica.

Adesso ogni parte interessata allo scambio di messaggi possiede due chiavi correlate tra loro: una per cifrare (pubblica) e l'altra per decifrare (segreta); queste chiavi sono differenti ed è impossibile ricavarne una dall'altra. La chiave di encryption può essere messa disposizione di tutti, pubblicata in un sito internet o allegata nelle e-mail, mentre quella di decryption deve essere mantenuta al sicuro. Una parte A che vuole inviare un messaggio cifrato ad una parte B, non deve fare altro che reperire la chiave pubblica di B e cifrare il messaggio con questa; la parte B può decifrare il messaggio poichè è l'unica a conoscenza della chiave privata corrispondente alla chiave pubblica con la quale i dati sono stati cifrati.

Ciò che è cambiato dalla cifratura simmetrica è che adesso le parti non si devono incontrare e scambarsi la chiave in modo sicuro, ma possono trovarla nella rete ad esempio sul sito web.
La realtà è però un pò diversa; oggi nessuno utilizza la crittografia a chiave pubblica per cifrare messaggi! Perchè?

Il motivo sono le performances. La cifratura asimmetrica è abbastanza lenta a cifrare un gran numero di dati e per questo l'approccio finale è una soluzione ibrida, un mix tra i due tipi di cifrature: si utilizza la crittografia a chiave pubblica per scambiarsi in modo sicuro la chiave segreta per poi scambiarsi dati con approccio simmetrico.

2.1.5 Dettagli

Requisiti di funzionamento:

1- viene utilizzato un unico algoritmo per la crittografia e la decrittografia con una coppia di chiavi: una per la crittografia e l'altra per la decrittografia.
2- il mittente ed il destinatario devono utilizzare una coppia di chiavi correlate ma distinte.

Requisiti per la sicurezza

3- una delle due chiavi deve essere mantenuta segreta.
4- Deve essere impossibile o quanto meno impraticabile decifrare un messaggio senza avere a disposizione altre informazioni.
5 -La conoscenza dell'algoritmo, di una delle due chiavi ed anche di campioni di testo cifrato è insufficiente per determinare l'altra chiave.

2.1.6 Algoritmo RSA

RSA è un cifrario a blocchi in cui testo in chiaro e testo cifrato sono rappresentati da numeri interi e le operazioni di encryption e decryption, che coinvolgono le chiavi pubbliche e private si basano sulla teoria dei numeri.

Il nome dell'algoritmo deriva dalla prima lettera dei cognomi di coloro che lo inventarono nell'Aprile del 1977: Ronald L. Rivest, Adi Shamir e Leonard M. Adleman.
sub{Generazione chiavi}

1- Siano p e q due numeri primi molto grandi
2- sia m = (p-1)(q-1)
3- sia n = pq
4-si trovi un numero d non necessariamente grande, relativamente primo ad n
5- si trovi e tale che de = 1 ( mod m)
6- la chiave pubblica è la coppia (d,n)
7- la chiave privata è la coppia (e,n)

Codifica di un messaggio
Il messaggio codificato è C(M) = Md ( mod n).

Decodifica di un messaggio
Il messaggio decodificato è M (C) =Ce ( mod n).

Pur conoscendo il meccanismo di codifica, la decodifica di un messaggio senza conoscere la chiave privata e è un operazione per cui anche il più potente dei calcolatori impiegherebbe secoli, riconducendo a noti problemi intrattabili nella scienza dei calcolatori, infatti:

1-Ignorando la chiave pubblica bisognerebbe calcolare la radice di ordine d, in aritmetica modulo n di M. Problema intrattabile.

2- Anche conoscendo la chiave pubblica d, il calcolo di e implicherebbe la necessità di trovare i numeri primi p e q che, se scelti nell'ordine di 10^{200}, producono di nuovo un problema intrattabile.

2.1.7 Funzioni HASH

Le funzioni hash sono piccoli gruppi di dati che servono ad identificare grandi quantità di dati. Queste funzioni sono pubbliche, tutti possono utilizzarle e non vi sono segreti a queste correlate.

Pensiamo di dover identificare o verificare un dato in una applicazione distribuita e mettiamo che questo dato sia di grandi dimensioni; non possiamo portarci con noi l'intera informazione poichè sarebbe una operazione troppo costosa; le funzioni hash ci permettono di avere una rappresentazione unica di una grande quantità di dati in poche decine di byte.

Le funzioni hash vengono dette one-way a causa della loro natura matematica: chiunque può calcolare una one-way hash function di un dato. Prendiamo il valore hash di questa tesi ad esempio; tutti lo possono calcolare, ma dato questo hash è impossibile creare un'altra tesi, diversa da questa, che produce lo stesso valore. E' in generale impensabile ed impraticabile costruire due dati distinti che producono lo stesso valore hash.

Le funzioni hash provvedono ai servizi di autenticazione ed integrità.

Svolgono un ruolo importantissimo in crittografia, dalla firma digitale a tutti i protocolli di autenticazione fino alla verifica dei dati; se scarichiamo un informazione dalla rete come possiamo essere sicuri che questa sia integra e che non si sia corrotta durante il download?

Per adesso non pensiamo che un utente malintenzionato abbia volutamente cercato di modificare la nostra informazione, ma pensiamo a dei comunissimi errori di trasmissione; scaricando il valore hash dei dati interessati, con una quantità trascurabile in termini di sovraccarico di banda al termine del download, avremo la sicurezza dell'integrità della nostra informazione.

Capitolo 3

Il mondo della Firma Digitale

3.1 Firma Digitale
Sono ormai vari anni che internet fa parte della nostra cultura; durante la sua crescita siamo passati da un sentimento di paura/timore sino ad uno di bisogno/amore con il risultato che oggi, nel 2005, ci fondiamo con esso e non ne possiamo fare a meno.

Ci sono però vari problemi legati al suo utilizzo: a causa del suo essere di natura incontrollabile c'è bisogno di portare in esso un certo grado di sicurezza, di affidabilità, soprattutto per coloro che di internet ne fanno una fonte di vita: sto parlando di e-commerce, amministrazioni ecc... Facciamo un esempio: una azienda che utilizza la rete per trasmettere il proprio bilancio aziendale agli organi statali deve avere garanzie che ciò che trasmette non verrà letto da terze parti o che non verrà modificato/falsificato da coloro che utilizzano internet in modo scorretto; inoltre lo stesso Stato deve avere la certezza che il bilancio che gli è stato inviato provenga effettivamente dall'azienda dichiarata.

Entrano in gioco così i vari servizi a cui la crittografia cerca di provvedere:

- Confidenzialità: garantisce che i dati siano accessibili in lettura solo alle parti autorizzate

- Integrità: assicura che un messaggio venga trasmesso senza ire modifiche da parte di terzi non autorizzati

- Autenticazione: assicura che l'origine di un messaggio sia correttamente identificata e che non sia stata falsificata

- Non-ripudiabilità: assicura che ne' il mittente ne' il destinatario potranno negare di aver trasmesso o ricevuto un messaggio

D'ora in poi parleremo di documento informatico, ovvero la rappresentazione informatica di atti, fatti o dati giuridicamente rilevanti.

Facciamo però un passo indietro: con il termine documento cartaceo si intende sia il supporto che il contenuto che in esso viene rappresentato; tramite la sottoscrizione autografa viene identificata la persona che ne assume la paternità, se ne sancisce l'autenticità ed il sottoscrittore stesso fa propri i contenuti rappresentati nel documento.
Un documento informatico può essere invece modificato o riprodotto infinite volte, ottenendo copie assolutamente identiche all'originale. Il contenuto è svincolato dal supporto.

Per restituire al documento informatico gli stessi requisiti assolti dalla sottoscrizione autografa di un documento cartaceo, occorre un tipo di autenticazione come la firma digitale che attribuisca al contenuto del documento informatico la piena validità legale.

Prima di poter parlare di firma digitale si deve parlare di firma elettronica; infatti la firma digitale è un particolare tipo di firma elettronica.

Per firma elettronica si intende l'insieme dei dati in forma elettronica, allegati oppure connessi tramite associazione logica ad altri dati elettronici, utilizzati come metodo di autenticazione informatica.

Si parla di firma elettronica avanzata come la firma elettronica ottenuta attraverso una procedura informatica che garantisce la connessione univoca al firmatario e la sua univoca autenticazione informatica, creata con mezzi sui quali il firmatario può conservare un controllo esclusivo e collegata ai dati ai quali si riferisce in modo da consentire di rilevare se i dati stessi siano stati successivamente modificati.

Al giorno d'oggi solo la crittografia a chiavi asimmetriche soddisfa i requisiti per la firma elettronica avanzata; esiste però un problema che non la rende equivalente alla firma autografa; è necessario fare un ulteriore passo avanti.

Anche se nelle varie direttive non compaiono mai, gli addetti ai lavori hanno introdotto due nuove definizioni: firma forte e firma leggera.

Normative sulla Firma Digitale si possono trovare ai siti: http://www.innovazione.gov.it/ita/normativa/normativa_firmadigitale.shtml e http://www.cnipa.gov.it/site/it-IT/Normativa/Leggi,_Decreti_e_Direttive

La firma forte è la tipologia di firma più importante dal punto di vista legale perchè è equivalente alla firma autografa. Affinchè una firma sia equivalente alla firma autografa è necessario che:

1- sia basata su un sistema di chiavi asimmetriche
2- sia generata con chiavi certificate
3- sia riconducibile a un sistema di chiavi provenienti da un certificatore ``accreditato'' e soggetto a vigilanza da parte di un organo definito
4- sia generata utilizzando un dispositivo sicuro

Una firma forte è la firma elettronica qualificata, ovvero una firma elettronica avanzata basata su un certificato qualificato e creata mediante un dispositivo sicuro per la creazione della firma.

Le direttive però conferiscono dignità giuridica anche agli altri tipi di firma ( leggera).

Esse non sono definibili tecnologicamente a priori. Possono essere gene-ra-te senza vincoli sugli strumenti e sulle modalità operative. E' ovvio che non offrono garanzie di interoperabilità se non in particolari condizioni di utilizzo come in gruppi chiusi di utenti.

Un giudice non potrà rifiutare in giudizio queste firme leggere, ma la loro ammissibilità nascerà dalla libera convinzione e non dall'obbligo di legge previsto per le cosiddette firme forti.

Adesso possiamo introdurre la firma digitale: un particolare tipo di firma elettronica qualificata basata su un sistema di chiavi crittografiche, una pubblica e una privata (Crittografia a chiave Pubblica), correlate tra loro, che consente al titolare tramite la chiave privata ed al destinatario tramite la chiave pubblica, rispettivamente, di rendere manifesta e di verificare la provenienza e l'integrità di un documento informatico o di un insieme di documenti informatici.

La firma digitale è quella parte della crittografia che fornisce i servizi di integrità dei dati, di autenticazione e non-ripudiabilità attraverso meccanismi a chiave Pubblica usati in maniera inversa: invece di cifrare un messaggio con la chiave pubblica (così da renderlo leggibile solo dal possessore della chiave privata) lo si cifra (ovvero firma) con la chiave privata; il risultato? tutti coloro che conoscono la chiave pubblica del firmatario possono provare che il mittente ed il messaggio sono realmente quelli dichiarati.

3.1.1 Firma Digitale in dettaglio

Vediamo ora come si svolgono i processi di firma e verifica di un messaggio.

Per messaggio in chiaro indichiamo il messaggio originale al quale non è stata applicata nessuna trasformazione.

Un utente che vuole firmare un messaggio invia, oltre al messaggio stesso, una versione cifrata con la propria chiave privata. Il destinatario del messaggio, che presupponiamo sia a conoscenza della chiave pubblica del mittente, decifra il messaggio con questa e verifica che il messaggio in chiaro corrisponda a quello appena decifrato; se è così il destinatario può provare che il messaggio non è stato modificato (integrità) e che il mittente è realmente quello dichiarato, ovvero quello in possesso della chiave privata con la quale il messaggio è stato firmato.

In realtà non viene inviata una nuova copia del messaggio cifrata con la chiave privata, ma viene allegato al messaggio in chiaro il ``Message Digest'' o ``Impronta Digitale'' di questo (cifrato con la chiave privata).

Il message digest è una funzione hash che applicata ad un messaggio produce una sequenza di lunghezza fissa legata univocamente con il messaggio; non è praticamente possibile creare due message digest identici da due messaggi diversi.

Il ricevente, dopo aver decifrato con la chiave pubblica il message digest, calcola un nuovo message digest sul messaggio in chiaro e se questo coincide con quello inviatogli la verifica ha successo.

Nasce adesso un ulteriore problema, ovvero di come il ricevente possa essere sicuro che la chiave pubblica in suo possesso sia realmente quella del mittente. Questo problema è risolto dai certificati, ovvero i documenti che attestano il legame tra un soggetto e la sua chiave pubblica.

3.2 Certificati Digitali

La verifica di una firma digitale apposta su di un documento non ci rende abbastanza sicuri della provenienza del messaggio; se la verifica ha successo un utente ha la certezza che il messaggio è autentico ed integro, ovvero che il messaggio proviene veramente dalla chiave privata che ha firmato il messaggio, ma non ha la certezza che una parte malintenzionata non abbia utilizzato una falsa coppia di chiavi per impersonare qualcun'altro.

Per esempio potrebbe succedere che un malintenzionato utilizzi un indirizzo e-mail rubato come proprio identificativo associando ad esso una coppia di chiavi falsa.

Nascono per questo motivo dei documenti che associano l'identità di una parte ad una coppia di chiavi e delle strutture che emettano e siano in grado di verificare questi documenti.

Stiamo parlando dei Certificati elettronici e dei Certificatori (Certification Authority).

Per certificatore si intende una autorità di fiducia che genera certificati e attesta le identità e le chiavi pubbliche di coloro per cui questi sono stati emessi.

In pratica un certificato elettronico consiste nelle informazioni personali del proprietario (nome, cognome, ecc..) e la sua chiave pubblica, il tutto cifrato con la chiave privata dell'ente certificatore.

Il certificato contiene anche la data di scadenza (periodo di validità), un numero seriale ed il nome dell'ente Certificatore che lo ha rilasciato.

Ecco quali sono i passi che si devono effettuare con successo per poter verificare la firma apposta su di un messaggio:

1- reperire da una fonte sicura la chiave pubblica del certificatore e del firmatario del messaggio (la chiave pubblica del firmatario può essere ottenuta anche dal certificato).
2- decifrare con la chiave pubblica del certificatore il certificato (verificando che esso appartenga ad una Autorità di Certificazione inclusa nell'elenco dei Certificatori, che non sia scaduto e non sia sospeso o revocato)
3- decifrare con la chiave pubblica del mittente il messaggio firmato (verifica della firma del messaggio) e controllare che questo coincida con quello inviato.
4- verificare la corrispondenza tra i dati (identità-chiavi) del certificato e i dati del mittente del messaggio

Un modo sicuro per autenticare una firma è quella di includere al messaggio più certificati: colui che riceve il messaggio, essendo in possesso delle chiavi pubbliche della CA (ottenute da una fonte sicura) decifra prima i certificati ed in seguito il messaggio.

Una firma può essere autenticata da una terza parte, la quale può a sua volta essere ulteriormente autenticata. Questo meccanismo gerarchico termina nella parte più alta della catena con una Certification Authority.

Molte volte questo complesso meccanismo non viene usato ed è sostituito da una catena a due livelli: certificatori e utenti (è il caso dell'Italia).

In Italia non esiste un organismo gerarchico per la sottoscrizione dei Certificati digitali. Non esiste una Certification Authority che assegna certificati ad altre -CA; la struttura si limita a due livelli:

1- Autorità di Certificazione
2- Possessori dei certificati

Al vertice vi è il presidente del CNIPA (Centro Nazionale per l'Informatica nella Pubblica Amministrazione) Dott. Livio Zoffoli che ha rilasciato un elenco di Autorità Accreditate per distribuire certificati firmato con la propria chiave privata.

La chiave pubblica del Dott. Zoffoli è stata opportunamente pubblicata nella gazzetta ufficiale.

Vediamo adesso un esempio: il nostro obbiettivo è quello di verificare la firma ed il certificato di Paolo Rossi rilasciato da ``Postecom CA1''.

Postecom ha a sua volta un proprio certificato; questo certificato è self-signed, ovvero dichiara che il proprio certificato è valido (``sicuro'').

Questa sarebbe una contraddizione se il certificato di "Postecom CA1" non fosse presente nella lista delle Autorità Accreditate rilasciata da CNIPA (non ci possiamo fidare a priori di Poste).

Ecco i passi che si devono effettuare per verificare la firma ed il certificato di Paolo Rossi:

1- Verificare che la firma di Paolo Rossi sia corretta.

2- Scaricare la lista di certificati rilasciata da CNIPA.

3- Verificare la correttezza della firma della lista (lista firmata dal Dott. Zoffoli).

4- Controllare che l'impronta digitale della chiave pubblica di Livio Zoffoli corrisponda a quella pubblicata nella gazzetta ufficiale.

5- Individuare all'interno della lista di Autorità scaricata dal CNIPA quella che ha rilasciato il certificato a Paolo Rossi, prenderne la chiave pubblica ed utilizzarla per verificare il certificato.

6- Scaricare la lista CRL del certificatore che ha rilasciato il certificato di Paolo Rossi.

7- Verificare le informazioni di Revoca del Certificato di Paolo Rossi.

Le direttive sulla firma digitale affidano il compito di verificare la validità di un certificato ai vari Certificatori i quali mettono a disposizione delle CRL ed hanno mezzi propri per mantere informazioni come il fingerprint di Zoffoli.

Le direttive indicano anche quali sono i software validi per poter verificare la firma digitale. Per la verifica dei certificati tutti utilizzano le Liste di Revoca.

3.2.1 Utilizzo dei Certificati

I certificati digitali sono utilizzati in diversi contesti:

- Applicazioni proprietarie: firma digitale, protezione di dati personali mediante crittografazione di documenti o di intere unità di memorizzazione, strumenti per l'autenticazione forte (strong authentication) degli utenti che accedono a reti o unità di elaborazione, controllo delle autorizzazioni all'utilizzo di risorse
- Applicazioni standard: posta elettronica (S/MIME), autenticazione di programmi eseguibili (Applet Java firmate, componenti Active X firmati, DLL firmate) ottenuti mediante download da reti insicure, accesso autenticato e con garanzia di riservatezza a server web (SSL/TLS), comunicazione riservata su reti pubbliche mediante reti private virtuali (VPN, IPSEC).

Il software scaricato da reti insicure (Internet) firmato da un ente certificatore ci dà la sicurezza di non apportare danni o di non eseguire azioni che possano recare danno alle nostre informazioni e/o alla nostra privacy.

3.3 Gli altri aspetti della Firma Digitale
3.3.1 La di_usione della _rma digitale in Europa

Nell'ambito del F.E.S.A. (Forum of European Supervisor Authority), il cui scopo è far incontrare rappresentanti dei vari organismi nazionali in Europa per l'armonizzazione dei principi e delle tecniche fondamentali che regolano la materia nei rispettivi Stati, si è proceduto alla verifica della diffusione della firma digitale. Da questa analisi, è emerso che l'Italia era, con 500.000 certificati lo stato con la maggior diffusione, seguita dalla Norvegia con 32.000, e dalla Germania con 26.000.
Nel primo trimestre 2004 il numero dei dispositivi rilasciati in Italia per la firma digitale ha superato 1.250.000 unità. La firma digitale generata in qualunque Stato membro della Comunità Europea deve, sulla base dei trattati comunitari, essere riconosciuta dagli altri Stati. Al fine di rendere agevole tale mutuo riconoscimento, è indispensabile che le norme nazionali di recepimento della Direttiva europea 1999/93/CE sulle firme elettroniche nei rispettivi Stati, forniscano un insieme comune di garanzie e certezze. Anche a tale fine diversi organismi fra cui l'EESSI, la Commissione sancita dall'articolo 9 della citata Direttiva europea, l'ETSI, il FESA, stanno lavorando per affinare la Direttiva stessa e realizzare nel contempo degli standard la cui applicazione consenta appunto di raggiungere un adeguato livello di fiducia in tutta la Comunità.

La diffusione della firma digitale in Europa ed il suo utilizzo fra gli Stati è una sfida non da poco. Basti pensare quanto è stato complicato raggiungere l'interoperabilità, perlomeno nel processo di verifica, in Italia, dove si aveva comunque il grande vantaggio derivante dal fatto che tutti i protagonisti (certificatori e titolari) dovevano sottostare alle medesime norme.

3.3.2 Il valore legale della Firma digitale in Italia

La firma digitale ha trovato l'impianto legislativo necessario per il proprio utilizzo con la pubblicazione, in data 15 aprile 1999, delle regole tecniche costituite dal DPCM 8 febbraio 1999 (oggi sostituito dal DPCM 13 gennaio 2004).

In data 27 gennaio 2000 veniva incluso, nell'elenco pubblico dei certificatori, il primo soggetto autorizzato a rilasciare dispositivi di firma digitale utilizzabili per poter sottoscrivere documenti informatici con la medesima validità giuridica della firma autografa. Un richiamo ben preciso all'articolo 2702 del codice civile ne sanciva, infatti, la validità giuridica, prevedendo appunto che itshape ``La scrittura privata fa piena prova, fino a querela di falso, della provenienza delle dichiarazioni da chi l'ha sottoscritta, se colui contro il quale la scrittura è prodotta ne riconosce la sottoscrizione, ovvero se questa è legalmente considerata come riconosciuta''.
Quindi la firma digitale era giuridicamente valida, fatta salva la possibilità per il presunto sottoscrittore di disconoscerne la paternità. In tale evenienza era la controparte, e non il sottoscrittore, a doverne dimostrare la reale paternità.

Diversamente se una firma è itshape ``legalmente considerata come riconosciuta'', ed è il caso ad esempio di una firma autenticata da un pubblico ufficiale, è il sottoscrittore che, per vederne nulli gli effetti, deve intentare una querela di falso.

Con il recepimento della Direttiva sulle firme elettroniche 1999/93/CE le cose sono cambiate. Difatti, già il primo provvedimento legislativo, il DLGS 23 gennaio 2002, n.10, modificando l'articolo 10
(L) ``Forma ed efficacia del documento informatico'' del DPR 28 dicembre 2000, n.445 – dove era confluito il DPR 10 novembre 1997, n.513, modificava, rafforzandolo, il valore giuridico di una sottoscrizione effettuata con firma digitale. Detto articolo, al comma 3, prescrive che itshape `` Il documento informatico, quando è sottoscritto con firma digitale o con un altro tipo di firma elettronica avanzata, e la firma è basata su di un certificato qualificato ed è generata mediante un dispositivo
per la creazione di una firma sicura, fa inoltre piena prova, fino a querela di falso, della provenienza delle dichiarazioni da chi l'ha sottoscritto''. Quindi, alla sottoscrizione con firma digitale ``forte'', (firma elettronica avanzata basata su certificato qualificato e generata per mezzo di un dispositivo sicuro per la generazione delle firme) viene data la medesima validità giuridica di una firma autografa autenticata da un pubblico ufficiale .

A tutte le altre possibili tipologie di firme elettroniche, cioè quelle cui mancano uno o più delle tre caratteristiche indicate nel periodo precedente, viene esplicitamente conferito valore probatorio.
In un procedimento legale tali firme elettroniche dovranno essere di volta in volta analizzate dal giudice (che si avvarrà certamente di un perito) che deciderà se ammetterle quali prove in giudizio. Questa previsione, che è stata resa esplicita per recepire senza dubbio alcuno quanto prescritto dalla Direttiva europea, era già presente nel nostro codice civile in quanto, lo stesso, prevede che nessuna prova in giudizio possa essere ricusata a priori.

3.3.3 Dove e come dotarsi di firma digitale

Coloro che intendono dotarsi di quanto necessario per poter sottoscrivere con firma digitale documenti informatici possono rivolgersi ai Certificatori (unici soggetti autorizzati).
L'elenco pubblico dei certificatori è disponibile via Internet per la consultazione; sono anche
disponibili i link ai siti web degli stessi sui quali sono indicate le modalità operative da seguire. E' bene precisare che vi sono alcuni soggetti che espletano questa attività esclusivamente per gruppi chiusi di utenti.
E' il caso del Centro Tecnico che esercita l'attività di certificatore esclusivamente per le PA appartenenti alla Rete Unitaria della Pubblica Amministrazione, piuttosto che l'Esercito Italiano o il Consiglio Nazionale del Notariato, che svolgono detta attività solo per gli appartenenti alle proprie strutture.
Esclusi questi soggetti vi sono, ad oggi, quattordici certificatori accreditati cui rivolgersi.

3.3.4 Il kit di firma digitale ed i costi

Per poter generare firme digitali è necessario essere dotati di un dispositivo sicuro per la generazione delle firme (costituito da una smartcard o da un token USB), un lettore di smartcard (nel caso in cui non si utilizzi il token USB), un software in grado di interagire con il dispositivo per la generazione di firme digitali e per la gestione del dispositivo stesso (es. per il cambio del PIN che ne consente l'uso).

Il costo del kit completo è variabile da certificatore a certificatore; a titolo orientativo è comunque possibile ottenere il kit completo ad un prezzo di circa 100 euro. Il certificato ha una scadenza, e deve essere quindi rinnovato periodicamente. In genere hanno una validità di uno o due anni, il rinnovo ha un costo orientativo di 10/15 euro per anno. E' bene evidenziare che tutti i certificatori prevedono delle condizioni economiche specifiche per forniture di particolare rilievo.

3.3.5 I cittadini

I cittadini che intendono utilizzare la firma digitale dovranno recarsi presso l'autorità di registrazione (RA) del certificatore per l'identificazione, la sottoscrizione del contratto di servizio e fornitura, per consegnare eventuale documentazione comprovante il possesso di titoli qualora desideri che detti titoli siano riportati all'interno del certificato. Le procedure per richiedere il rilascio del certificato (e la fornitura del dispositivo di firma) sono peculiari di ogni certificatore anche se, nella sostanza, prevedono la medesima attività. Dette procedure sono riportate nel manuale operativo di ogni certificatore. Nella scelta del certificatore è bene verificare quali servizi aggiuntivi sono forniti dagli stessi (es. certificato di autenticazione e crittografia), la durata del periodo di validità del certificato ed i costi per il rinnovo.

3.3.6 Le Imprese

Quando un'impresa decide di dotare un numero considerevole dei propri dipendenti del kit di firma
digitale, contatta i vari certificatori per scegliere, sulla base del numero dei kit necessari, del costo complessivo dell'operazione e dei servizi accessori offerti, quello che meglio soddisfa le proprie esigenze.
Inoltre, è piuttosto frequente che vi siano accordi al fine di demandare all'impresa stessa l'attività di registrazione e di verifica dell'identità del titolare del certificato.
Questa pratica viene spesso utilizzata in quanto comporta diversi benefici a tutti i soggetti coinvolti (dipendente, impresa e certificatore). Il dipendente non deve recarsi fisicamente presso l'autorità di registrazione del certificatore e l'impresa ha un risparmio notevole in termini di ore lavoro spese dai dipendenti oltre al controllo diretto dei certificati emessi per i propri dipendenti con procedure snelle e rapide che consentono di richiedere sospensioni e revoche dei certificati stessi. Il certificatore trae vantaggio dal fatto che non deve impegnare risorse umane per il riconoscimento dei titolari, la verifica dei titoli e di eventuali incarichi o ruoli svolti per l'impresa richiedente.

3.3.7 Le pubbliche Amministrazioni

Le Pubbliche Amministrazioni possono agire come descritto nel paragrafo precedente per le imprese o, in alternativa, possono richiedere di essere accreditate (iscritte quindi nell'elenco pubblico dei certificatori) utilizzando in realtà le infrastrutture tecnologiche di uno dei soggetti già iscritti nell'elenco stesso. In questo caso, oltre ai vantaggi descritti nel paragrafo precedente, ottengono il vantaggio di risultare, nella fase di verifica di un documento informatico sottoscritto con firma digitale da un proprio dipendente, quali soggetti che emettono e garantiscono le informazioni inerenti il dipendente stesso.

3.3.8 Lo strumento Firma digitale integrato nel processo di e-government

Fino dalla sua nascita la firma digitale è stata una punta di diamante del Governo Italiano nell'ambito dei processi di semplificazione amministrativa. Infatti la firma digitale è indispensabile nell'automazione dei processi amministrativi, nella gestione informatizzata dei flussi documentali e in tutti quei procedimenti dove si vuole l'eliminazione del documento cartaceo (smaterializzazione del procedimento amministrativo).
Sono ormai numerose le applicazioni che utilizzano la firma digitale nell'ambito della pubblica
amministrazione. Queste stanno coinvolgendo le imprese, con l'obbligo di trasmissione telematica dei bilanci alle Camere di Commercio, la pubblica amministrazione, con la piena smaterializzazione dei mandati di pagamento con tutti i flussi firmati digitalmente, i cittadini, con la possibilità già descritta precedentemente di inviare istanze e dichiarazioni alla pubblica amministrazione in modalità telematica.
I professionisti saranno sempre più coinvolti nell'utilizzo della firma digitale per gli atti notarili, gli atti giudiziari nell'ambito del processo telematico e per le dichiarazioni fiscali.
La diffusione della Carta d'Identità Elettronica e della Carta Nazionale dei Servizi non potrà che favorire ulteriormente lo sviluppo ed il conseguente utilizzo della firma digitale da parte dei cittadini.
A livello internazionale c'è ancora da lavorare per garantire l'interoperabilità almeno a livello comunitario, ma dopo alcuni scetticismi da parte degli organismi comunitari il processo di regolamentazione è avviato anche in tal senso.
Al momento, in ogni caso ci si può dichiarare soddisfatti, visto che l'Italia, primo paese ad avere introdotto la firma digitale nella propria legislazione, è anche il primo paese a superare la soglia del milione di titolari di sottoscrizione digitale.

Capitolo 4

Gli Standard Utilizzati

Il mondo della firma digitale è un campo che ruota su molti standard che vanno da quelli crittografici, come quelli che danno specifiche sugli algoritmi, sino a quelli che descrivono i protocolli per accedere ai dispositivi che contengono le coppie di chiavi.

In questo capitolo tratteremo gli standard RSA che si integrano con MIME ed S/MIME per rendere i file cifrati o firmati compatibili tra sistemi eterogenei. Andremo anche ad analizzare il contenuto dei certificati digitali per sapere quali sono le informazioni che devono essere estratte da questi per poter effettuare correttamente il processo di verifica.

 

4.1 PKCS
In crittografia PKCS si riferisce ad un gruppo di Standard Crittografici a Chiave Pubblica (Public Key Cryptography Standards) divisi e pubblicati dai Laboratori RSA in California. RSA Security ha il compito di sfornare standard basati sull'algoritmo di cifratura a chiave asimmetrica (pubblica-privata) RSA.
Vi sono ben 15 versioni standard, da PKCS#1 a PKCS#15, ognuno dei quali tratta un tema-standard ben preciso:

 


4.1.1 PKCS#1

Questo standard definisce le linee guida per l'implementazione del sistema crittografico a chiave pubblica basato su RSA. PKCS#1 definisce i seguenti aspetti: le primitive crittografiche, gli schemi di cifratura e di firma, la codifica ANS.1 per rappresentare le chiavi ed identificare gli schemi.

4.1.2 PKCS#7

Questo standard definisce una sintassi generale per i dati ai quali sono state applicate funzioni di cifratura e/o firma digitale.
PKCS#7 è divenuto lo standard di S/MIME oltre che del retrodatato PEM (S/MIME è una evoluzine di PEM). Le sue applicazioni non si limitano alla posta elettronica; PKCS#7 è divenuto la base per la sicurezza dei messaggi nei sistemi di pagamento (transazioni) e nello standard PKCS#12 utilizzato per esportare le informazioni personali (certificati e chiavi).

PKCS#7 definisce principalmente una struttura dati per incapsulare una serie di oggetti ai quali sono state applicate funzioni crittografiche. Questo tipo di struttura è ricorsiva, ovvero permette di incapsulare altre strutture dello stesso tipo.
I tipi di strutture incapsulate vengono riportate nel campo ``ContentType''; questo campo può assumere i seguenti valori:

- Data = sequenza di byte con codifica DER

- SignedData = messaggio firmato da una o più parti

- EnvelopedData = messaggio cifrato con un algoritmo a chiave simmetrica

- SignedAndEnvelopedData = messaggio firmato e cifrato

- DigestData = messaggio e message digest del messaggio

- EncryptedData = messaggio cifrato, le gestione delle chiavi è lasciata ad altri

Tutti questi tipi di dati riportano anche informazioni sul tipo di algoritmo utilizzato, sui firmatari e sui certificati dei firmatari.
Un dato a cui è stata applicata la firma digitale contiene quindi informazioni aggiuntive come la chiave pubblica del firmatario.
Gli ultimi due tipi di contenuto sono detti espliciti, poichè permettono di racchiudere i dati ai quali sono state applicate trasformazioni crittografiche in strutture particolari da includere a parte.
Solitamente si usano le strutture implicite in cui il messaggio e la sua trasformazione sono legati assieme.

4.1.3 PKCS#11

Le specifiche pkcs#11 sono state sviluppate con l'obbiettivo di definire una interfaccia di programmazione ad alto livello che mascheri la logica operativa del particolare dispositivo crittografico ( smartcard, token usb, scheda PCMCIA) presentando alle applicazioni un dispositivo crittografico detto Cryptographic Token.
Tutto ciò ha portato pkcs#11 ad essere uno standard ampiamente utilizzato dalle applicazioni che utilizzano dei dispositivi crittografici sicuri quali sono le smartcard.

Le specifiche PKCS#11 definiscono una api chiamata Cryptoky (Cryptographic Token Interface) che implementa una interfaccia tra l'applicazione e il modello del dispositivo indipendentemente dal tipo (smartcard ecc.). Questa api permette di accedere a qualunque tipo di dispositivo svincolando le applicazioni dai dettagli implementativi che come vedremo sono lasciati ai costruttori dei vari dispositivi.

Le applicazioni divengono portabili permettendo al sistema di condividere più dispositivi.
L'architettura del sistema basato su Cryptoky è così composta: vi è uno slot connesso al sistema; questo può essere un lettore smartcard o un qualsiasi altro terminale. Gli slot, che possono essere più di uno e condivisi tra le varie applicazioni, comunicano con i token (smart card). Cryptoky comunica con gli slot attraverso un software di sincronizzazione che solitamente viene eseguita dal sistema operativo. Le varie applicazioni richiedono le varie funzionalità Cryptoky grazie a collegamenti statici o dinamici con le varie librerie (dll) che i produttori dei token mettono a disposizione.

Token
L'implementazione di Cryptoky mappa la struttura fisica del token in una struttura logica; questa è composta da tre oggetti principali:

- Data: dati generici creati dalla applicazione che li ha generati.
- Certificate: contiene un certificato digitale
- Key: può contenere chiavi simmetriche e assimetriche.

Gli oggetti all'interno del token hanno visibilità diverse: vi sono quelli pubblici e quelli privati, che sono visibili sono dopo l'inserimento di un codice PIN (Personal identifier number).

4.2 X.509: standard per i certificati

X.509 venne presentato per la prima volta nel 1988 e il suo sviluppo cominciò insieme allo standard X.500. La prima versione presupponeva uno stretto sistema di gerarchie di Certification Authority (CA) per presentare e garantire un certificato, in contrasto con il modello della rete di fiducia (web of trust), utilizzato da PGP, dove chiunque (non solo CA particolari) può firmare e quindi attestare (certificare) la validità delle chiavi altrui. La Versione 3 di X.509, (quella attuale) include flessibilità tipiche di altre tipologie di reti e filtri: può essere utilizzato in una rete di fiducia peer-to-peer come quella di OpenPGP, anche se raramente è implementata in questo modo. Il termine certificato X.509 si riferisce generalmente al profilo di ``certificato PKI'' e di ``revoca del certificato'' (CRL) dell'IETF (Internet Engineering Task Force, comunità aperta di tecnici ) dello standard X.509 v3, come descritto nella RFC 3280. Una PKI è una infrastruttura che provvede ai servizi di crittografia a chiave pubblica.

Nel sistema X.509, una CA rilascia un certificato che accoppia una chiave pubblica ad un Nome Distintivo (Distinguished Name) seguendo la tradizione del X.500, oppure ad un Nome Alternativo (Alternative Name) come potrebbe essere un indirizzo e-mail o un record DNS.

Un root certificate fidato di un'azienda può essere distribuito a tutti i dipendenti, per far si che possano usare la PKI aziendale. Browser come Mozilla, Netscape, Explorer ed Opera vengono distribuiti con alcuni root certificate preinstallati, rendendo possibile il funzionamento dei certificati SSL di alcuni grossi distributori che hanno pagato per questo servizio; in pratica chi sviluppa il browser determina quali CA sono terze parti fidate. Nonostante questi root certificate possano essere eliminati o disabilitati, raramente gli utenti lo fanno.

I certificati X.509 sono descritti indipendentemente dalla piattaforma usando la codifica ANS.1 (è una codifica per rappresentare le strutture dati in sistemi eterogenei).

X.509 include anche gli standard per le implementazioni di Certificate Revocation List (CRL, liste di revoca di certificati), un aspetto spesso sottovalutato dei sistemi PKI.

La modalità di controllo della validità di un certificato approvata dall'IETF si chiama Online Certificate Status Protocol (OCSP).

4.2.1 Struttura di un Certificato

La struttura di un certificato digitale X.509 v3 è la seguente:

- Certificato
     x Versione
      x Numero seriale
      x ID dell'algoritmo
      x Ente emettitore
      x Validità
           * Non prima
           * Non dopo
      x Soggetto
      x Informazioni sulla chiave pubblica del soggetto
            * Algoritmo per l'utilizzo della chiave pubblica
            * Chiave pubblica
      x Codice identificativo univoco dell'emittente (facoltativo)
      x Codice identificativo univoco del soggetto (facoltativo)
      x Estensioni (facoltativo)
- Algoritmo di firma del certificato
- Firma del certificato

I codici identificativi univoci dell'emettitore e del soggetto sono stati introdotti nella versione 2, le "Estensioni" nella versione 3.
Estensioni comuni per i file contententi i certificati X.509:

.CER - certificato codificato con DER, a volte sequenze di certificati;
.DER - certificato codificato con DER;
.PEM - certificato codificato con Base64
.P7C,.P7B - struttura SignedData PKCS#7, senza dati, solo il/i certificato/i o la/le CRL (Certificate revocation list);
.P12,.PFX - PKCS#12, può contenere certificati e chiavi pubbliche e private (protette da password). E' utilizzato per esportare informazioni private (chiave privata, pubblica e certificato) ed è utilizzato da molte applicazioni quali browser web e programmi di posta ellettronica per importare gli ID digitali (ovvere profili per firmare, verficare, cifrare e decifrare informazioni).

4.2.2 Metodi di Verifica dei Certificati

Nello standard X.509 le PKI, ovvero le infrastrutture che provvedono ai servizi di crittografia a chiave pubblica, supportano due modalità di verifica della validità di un certificato:

CRL: certificate revocation list
OCSP: online certificate status protocol

Entrambe ci danno informazioni sullo stato dei certificati; può accadere infatti che un certificato perda la sua validità prima del periodo di scadenza poichè ad esempio il proprietario comunica che la sua chiave è stata compromessa. Nel caso delle CRL, il certificatore pubblica una lista di certificati che non sono più validi.

Coloro che vogliono verificare un certificato possono accedere a queste liste (od eventualmente scaricarle) e controllare se è presente e quindi non più valido.

Le CRL sono distribuite nel formato standard X.509 e vengono aggiornate periodicamente.

I certificati all'interno sono identificati tramite il ``Serial Number'' e rimossi quando raggiungono la data di scadenza (i certificati che raggiungono la data di scadenza non vengono inseriti nelle CRL). In realtà non vengono tolti immediatamente ma solo dopo un periodo di tempo necessario per far si che sia possibile stabilire la validità di documenti firmati in una certa data e ricevuti dopo la data di scadenza. Un utente potrebbe voler verificare se il dato certificato era presente nella CRL al momento della spedizione.

Le Liste di Revoca dei Certificati presentano però un punto debole: il periodo che intercorre tra una pubblicazione e la successiva. Cosa succede se un certifcato diviene non più valido ito dopo la pubblicazione di una CRL?

Nel periodo che intercorre tra una pubblicazione ed un'altra il certificato (ormai falso) risulterà valido, senza parlare delle conseguenze!.

E' per questo che si è studiato un nuovo metodo, più veloce e sicuro: OCSP (Online Certificate Status Protocol).

OCSP è un protocollo che permette di verificare la validità di un certificato senza ricorrere alle Liste di Revoca degli stessi. Fa parte dello standard X.509 e viene descritto in RCF 2560.

L'Online Certificate Status Protocol è lo standard emergente dell'IETF (Internet Engineering Task Force) destinato al controllo della validità dei certificati digitali nel corso di una determinata transazione. OCSP permette di condurre queste verifiche in tempo reale, risparmiando tempo e denaro e fornendo alle attività di e-business un sistema più rapido, semplice ed affidabile per la validazione dei certificati digitali rispetto a quello offerto dal tradizionale scaricamento ed elaborazione delle CRL (Certificate Revocation Lists).

L'architettura del protocollo è di tipo client server; da un lato abbiamo i vari client che effettuano una richiesta (OCSP request) per controllare la validità del certificato, mentre dall'altra abbiamo il server (responder) che cerca di soddisfare tutte le richieste inviando messaggi di validità ("VALIDO", "REVOCATO" o "SCONOSCIUTO").

OCSP ha alcuni vantaggi rispetto CRL:

- elimina la necessità per i client di scaricare ed analizzare le liste di revoca.
- provvede ad un migliore utilizzo della banda dal momento che un messaggio OCSP ha una dimensione trascurabile rispetto alle CRL.
- supporta una catena fidata di OCSP request tra i vari responder. Questo permette ai clienti di comunicare con un responder fidato per interrogarne un altro.
- OCSP è più efficiente delle CRL e quindi scala in modo migliore.

4.2.3 CRL in dettaglio

La legge in campo di Firma Digitale impone ai Certificatori di mettere a disposizione una lista di revoca CRL per poter controllare le varie informazioni sullo stato dei Certificati che gli stessi hanno rilasciato.

Proviamo ad aprire un certificato di un Ente Certificatore ed andiamo a guardare i vari campi; noteremo che vi sono dei campi (sono delle estensioni) nei quali sono indicati i vari punti di distribuzione delle Liste dei Certificati Revocati. In ogni certificato il certificatore dichiara l'indirizzo internet dove, nel caso di revoca o sospensione del certificato, inserirà l'informazione.

I vari software per la firma Digitale non fanno altro che, una volta verificato il certificato, collegarsi all'URL dichiarato e controllare le informazioni sulla revoca. Questi sono gli obblighi che i certificatori hanno.

Vi sono varie modalità di accesso a queste liste; si possono recuperare tramite un url o tramite ldap. Nel primo caso basta scaricare il file *.crl mentre nel secondo si deve accedere ad un server LDAP messo a disposizione dal certificatore.

4.3 MIME

Multipurpose Internet Mail Extensions (MIME) è lo standard Internet per il formato delle e-mail. Virtualmente tutte le e-mail inviate tramite SMTP sono in formato MIME.

SMTP, che sta alla base della trasmissione delle e-mail, supporta soltanto caratteri ASCII a 7 bit; MIME fornisce dei meccanismi per inviare altri tipi di informazioni nelle e-mail, dai supporti per le lingue, ai file multimediali. La conversione dei messaggi in formato MIME è fatto in automatico dai client email e dai mail server.

Ogni messaggio è composto da una intestazione e dal contenuto del messaggio stesso.

Le applicazioni di MIME non si riducono solamente all'utilizzo della posta elettronica: grazie alla codifica che esso attua può essere considerato uno standard per quanto riguarda la trasmissione multipiattaforma di informazioni complesse e strutturate.

4.4 S/MIME

S/MIME (Secure / Multipurpose Internet Mail Extensions) è lo standard Internet per i dati crittografati e/o firmati incapsulati in MIME.

S/MIME è un miglioramento di PEM (Privacy Enhanced Mail) ed è definito in RFC 2311.
Fornisce alle applicazioni di posta elettronica i seguenti servizi:

- autenticazione
- integrità
- non ripudio
- Confidenzialità

Grazie ad S/MIME le comuni applicazioni per le e-mail possono inviare e ricevere messaggi cifrati e firmati.

S/MIME utilizza lo standard PKCS#7 sopra descritto per applicare funzioni crittografiche ai dati ed inserirli in un ``Body Part''. Per questo S/MIME cerca di dare una base di interoperabilità tra i senders e receivers imponendo una serie di regole per stabilire quali caratteristiche PKCS#7 debbano essere implementate da ambo le parti.
Vengono definite nuove entità MIME per supportare i vari tipi PKCS#7:

I dati da firmare o cifrare sono entità MIME che vengono processate secondo PKCS#7 ed inserite nuovamente in oggetti MIME. Il prodotto PKCS#7 consiste nella codifica BER (Basic Encoding Rules) dell'entità relativa definita tramite la sintassi ANS.1. Il nuovo dato assume una intestazione specifica, con content-type application/pkcs7-mime e deve avere una delle estensioni sopra citate.

Capitolo 5


Il Prototipo di Applicazione

E' stata scelta la parola prototipo di applicazione in quanto questo progetto può essere considerato una ``macchina'' di prova, un programma disegnato per scopi dimostrativi.
Vi sono anche altri motivi legati all'utilizzo del termine ``prototipo'' e questi sono tutti dovuti alle differenze che il mio progetto ha con l'applicazione Certificata e riconosciuta legalmente per la firma digitale qual'è l'applicazione FirmaOK!gold di Poste Italiane, differenze che la rendono per certi aspetti peggiore e migliore di quella di PosteCert. L'applicazione di Postecert è stata il modello funzionale sul quale si è basata la costruzione e sviluppo dell'applet sia dal punto di vista progettuale/implementativo che di usabilità.
Non vogliamo però focalizzare l'attenzione su quale applicazione può essere la migliore, (anche perchè il prototipo sviluppato implementa solo alcune delle funzionalità disponibili in FirmaOK!gold), ma quali interessanti caratteristiche una applicazione di firma come FirmaOK!gold potrebbe introdurre/integrare per migliorare la portabilità e la interoperabilità con i vari dispositivi.


5.1 L'applicazione

In questa tesi è stata realizzata una applicazione per la firma digitale, ovvero un prodotto software che prende dei file ed applica a questi delle trasformazioni crittografiche che garantiscono ad una parte servizi di autenticità, integrità e non ripudiabilità.
A sua volta, dati dei file con firma digitale applicata ad essi, l'applicazione è in grado di verificare il firmatario, la validità della firma e del corrispondente certificato.
Inoltre grazie all'utilizzo di smart card come supporto alla crittografia l'applicazione è in grado di reperire in modo sicuro le informazioni (coppia di chiavi) dal supporto e con queste firmare file.

Tutto ciò è a grandi linee quello che l'applicazione è in grado di eseguire; ma prima di presentare il prototipo vero e proprio (una applet Java), voglio descrivere come sono arrivato fino a qui, parlando dei problemi e delle scelte che ho incontrato, fatto, risolto, aggirato e purtroppo anche non superato.

5.1.1 Le scelte ed il Contesto

All'inizio del progetto mi sono ritrovato con una buona idea di base (firma digitale con l'uso di smart card), una discreta voglia di conoscenza, tanta umiltà, della testardaggine, ed un mare di tecnologie e standard su cui ``nuotare''. L'implementazione delle varie funzioni non è stata la parte difficile di questo lavoro anche se non è stato semplice trovare del materiale per capire come farlo; ciò che mi ha messo a dura prova sono state le scelte che ho dovuto fare; quando sono risultate sbagliate mi hanno arricchito ma fatto perdere molto tempo. Decidere con quale linguaggio e con quali librerie implemtentare il tutto mi ha creato non pochi problemi: sono passato dallo standard PC/SC all'OpenCard FrameWork fino all'implmentazione IBM e IAIK di PKCS#11 (CryptoKi).

Quello che vorrei far capire è che quando parliamo di Applicazioni che riguardano la ``firma digitale'' non ci riferiamo soltanto al meccanismo di cifratura e decifratura; per quello basta soltanto scrivere del codice che produca un risultato corretto; quello con cui ho avuto a che fare sono gli standard utilizzati in Italia e le influenze che gli aspetti legali hanno sulla firma e sui certificati.

5.1.2 Il linguaggio: JAVA

La scelta è stata quella di utilizzare il linguaggio Java per sviluppare la mia applicazione.
I motivi di questa scelta sono i seguenti: un linguaggio Object Oriented per risolvere in maniera elegante e riusabile i vari problemi, l'ampia disponibilità di librerie (gratuite e non) che vengono messe a disposizione, l'indipendenza dalla piattaforma e le caratteristiche di sicurezza che questo presenta.
Garantire che l'applicazione possa girare su più sistemi è, in pratica, garantire che il codice possa essere compilato sui sistemi più disparati.
Il problema si riduce quindi a trovare un compilatore in grado di offrire queste garanzie e una scelta ponderata in questo senso è ricaduta sui linguaggi ANSI C e JAVA. In particolare Java è in grado di generare codice compilato da far funzionare all'interno di una qualsiasi Virtual Machine (disponibile per tutte le piattaforme).

Una delle più conosciute security feature di Java è la cosiddetta SANDBOX. La sandbox è essenzialmente una collezione di risorse sicure a cui un pezzo di codice può accedere. Le applet girano di default in una sandbox.

Un'altra importante caratteristica di Java è la mancanza di puntatori. Questa può essere vista come una mancanza piuttosto grande, ma dal punto di vista della sicurezza, l'impossibilità di accedere direttamente alla memoria, è un grande vantaggio.

Dispone inoltre di un ``byte code verifier'' e di un class loader: il ``verificatore'' di codice può prevenire contro applicazioni pericolose mentre il compito del class loader è quello di caricare specifiche classi all'interno della VM che lavora con un security manager; questo controlla che vengano rispettate tutte le politiche di sicurezza.

5.2 La smart card a supporto della crittografia

La crittografia, sebbene fornisca delle tecniche estremamente eleganti e potenti per assicurare l'integrità e la riservatezza delle informazioni, registra un punto debole: la difficoltà di proteggere in maniera adeguata le chiavi private. Difatti, se una chiave adottata per cifrare un insieme di informazioni non è adeguatamente protetta (ad esempio è memorizzata sull'hard disk di un PC), un malintenzionato potrebbe impossessarsene e quindi decifrare tutte le informazioni vanificando gli sforzi crittografici compiuti.

La smart card a microprocessore, grazie alle caratteristiche di protezione dei dati di cui è dotato il microchip (come l'impossibilità di modificare le chiavi) ed alla presenza di un coprocessore crittografico che gli consente di eseguire le principali funzioni crittografiche on-board, (senza fare uscire ed esporre le chiavi private all'ambiente operativo delle applicazioni ) si propone come mezzo adeguato a proteggere le chiavi private rilanciando la crittografia come supporto tecnologico di base per lo sviluppo di sistemi informatici sicuri e riproponendo in maniera decisa la firma digitale come sicuro ed insostituibile strumento per l'autenticazione e l'identificazione degli individui, per la verifica dell'integrità di insiemi di dati e per il non ripudio delle transazioni.
Le applicazioni con smart card coprono campi che vanno dal settore pubblico e privato a quello delle telecomunicazioni. In ogni caso le smart card sono utilizzate per la memorizzazione sicura dei dati e per autenticare e proteggere le transazioni che avvengono nella rete.
Le applicazioni posso toccare la telefonia fissa e mobile, il settore bancario, e-government (carta di identià elettronica e carta nazionale dei servizi), trasporti, settore militare e privato.

Gli standard

Fino a qualche anno fa, le differenze esistenti tra le varie smart card disponibili sul mercato e tra i numerosi dispositivi di lettura rendevano estremamente complesso lo sviluppo di applicazioni che interagivano con le stesse.
A causa delle notevoli differenze tra le molteplici implementazioni native, solo un numero ristretto di programmatori altamente specializzati era in grado di scrivere applicazioni che funzionavano però solo con un ristretto numero di smart card e lettori.
Lo sviluppo tecnologico degli ultimi anni unito alla domanda sempre più forte di applicazioni con smart card, ha portato alla definizione di un insieme di specifiche standard che consentisse l'interoperabilità tra smart card e lettori di diversa fabbricazione. Lo standard ISO 7816 definisce le caratteristiche fisiche, elettriche e funzionali che sono alla base di una smart card allo scopo di standardizzare sia le proprietà esterne (dimensioni, disposizione dei contatti elettrici) sia i protocolli di comunicazione tra il circuito integrato, il terminale di lettura (lettore smart card) e le applicazioni che sono eseguite sul computer. Tuttavia tale standard, sebbene da un lato definisca le fondamenta tecnologiche delle smart card, dall'altro propone una interfaccia di programmazione veramente a basso livello e soprattutto, è soggetto a differenti interpretazioni. Ne consegue che, nonostante l'interoperabilità tra le smart card sia stata ad un certo livello effettivamente raggiunta, la programmazione delle stesse è rimasta ancora una attività ristretta a pochi specialisti del settore, tipicamente molto costosi e comunque dipendente dal terminale di lettura.
In tale panorama, numerose aziende del settore hanno formato dei gruppi di lavoro per tentare di definire un documento di specifiche che potessero rendere finalmente interoperabili smart card e lettori di diversa fattura e consentissero di semplificare lo sviluppo di applicazioni con smart card, avvicinandolo il più possibile ai paradigmi di programmazione tradizionali. Ecco quali sono le implementazioni più conosciute:

1- il PC/SM Workgroup, che ha definito le specifiche PC/SC, ha il pregio di aver standardizzato i terminali di lettura su piattaforma Microsoft mediante una definizione precisa dei requisiti hardware e delle interfaccie tra terminale, PC e Sistema Operativo.

2- le specifiche PKCS#11 e PKCS#15 che propongono un modello di dispositivo crittografico astratto che abbraccia tutte le smart card crittografiche, definiscono una API ad alto livello in C/C++ e JAVA per la scrittura di applicazioni portabili che interagiscano con questa e infine stabiliscono la struttura logica e fisica del file system sulla smart card.

3- OpenCard Consortium (insieme di produttori tra i quali IBM, Netscape, Sun, NCI, Gemplus, Siemens, Visa) ha definito l'OpenCard FrameWork costituito da un insieme di classi Java il cui obbiettivo è proporre da un lato un'interfaccia unica con la smart card e con il lettore al fine di assicurare interoperabilità e dall'altro un modello di programmazione basato su un linguaggio di programmazione semplice, diffuso e multipiattaforma quale è Java.

4- le specifiche EMV che definiscono le caratteristiche di una smart card che deve operare in ambito bancario.

5.2.1 Le librerie utilizzate

Il primo passo per lo sviluppo della mia applicazione è stato lo studio, lento e faticoso, di OpenCard FrameWork.
Questo progetto, anche se portato avanti da grandi produttori come IBM, GEMPLUS e SUN, è stato abbandonato nel 2000/2001 e quindi anche a causa di un mancato supporto da parte degli sviluppatori, ho deciso di utilizzare l'implementazione dello standard PKCS#11 (Cryptoki) fornita dall'università della tecnologia di Graz. ``IAIK PKCS#11'' è una libreria Java che permette l'accesso a moduli PKCS#11. Un modulo è a sua volta una libreria. Questa è legata ad uno specifico hardware (smart card, usb token). L'implementazione di Graz permette di accedere a qualsiasi hardware crittografico da usare per firmare, cifrare e decifrare dati.

Il modello della libreria è un modello stratificato; questo consiste nel Object Oriented Java Wrapper Api per PKCS#11, il (non Object Oriented) Java Wrapper API for PKCS#11 e il modulo nativo (gli strati in verde).

 

Il livello più basso è il modulo PKCS#11 per la smart card che il produttore fornisce. Solitamente questo modulo è una dll linkata dinamicamente o staticamente. Come le frecce mostrano, il livello più alto dipende dallo strato sottostante ma non viceversa. Questo significa che si può usare il java Wrapper per PKCS#11 direttamente ed implementare una applicazione usando un approccio Object Oriented e non. L'approccio non user-oriented può essere utile per creare piccole applicazioni e quindi non utilizzare tutte le classi del package.

5.3 I servizi e le funzionalità

L'applicazione mette a disposizione le seguenti funzionalità:

1- firmare file attraverso l'uso degli algoritmi RSA e SHA-1. I file firmati vengono salvati nel formato S/MIME (*.p7m) per garantire una compatibilità con i software di firma digitale presenti nel panorama Italiano della sicurezza.

2- verificare la firma apposta su di un file (*.p7m). Preso in input un file in formato S/MIME PKCS#7 l'applicazione verifica la firma decifrando il file (o meglio l'hash del file) con la chiave pubblica presente nel certificato contenuto nel file.

3- verificare il certificato dell'ente Certificatore, ovvero verificare la credibilità di un certificato. Questa funzionalità permette di identificare e verificare l'ente Certificatore che lo ha rilasciato.

4- verificare le informazioni sulla revoca del certificato. L'applicazione scarica una lista CRL e controlla se il certificato è presente. Gli enti certificatori mantengono una lista di certificati che sono stati revocati: per verificare che lo stesso non sia stato revocato si deve accedere a questa lista e controllare che il certificato (il suo numero di serie) non sia presente. La legge Italiana ha imposto l'obbligo per gli enti certificatori di implementare la verifica CRL.

5.3.1 Il punto di riferimento

Il kit smart card e lettore che ho in dotazione è quello che veniva fornito nel 2004 da Poste Italiane, precisamente da PosteCert, il servizio di Firma Digitale di Poste. Il kit comprende 3 componenti:

- smart card GEMPLUS GEMGATE 32K con sistema operativo CARDOS (librerie gclib.dll).
- lettore GEMPLUS TWIN con interfaccia USB.
- software per la Firma Digitale ``FIRMAOK!gold''.

Ho basato lo sviluppo della mia applicazione sul software firmaOK!gold di Postecert. Usando ed analizzando il prodotto di Poste Italiane ho notato una grande semplicità di utilizzo del tool: è possibile aggiungere dei file ed in seguito firmarli, verificarli, cifrarli o decifrarli con solo due click di mouse.


Poste Italiane ha fatto sicuramente un buon lavoro, un tool semplice che soddisfa a pieno tutte le esigenze dei privati che vogliono utilizzare la firma digitale.
FirmaOK!gold ha una interfaccia minima ed essenziale; questa è divisa in due aree con i rispettivi bottoni: una per file da firmare o cifrare e un'altra per i file che hanno ito trasformazioni crittografiche.
Nella parte alta vi è un menu che permette di eseguire le semplici operazioni crittografiche, ma anche di impostare/aggiornare i vari certificati, il pin ed il puk della smart card.
E' inoltre possibile accedere ad un archivio di certificati per poter controllare e/o aggiornare la validità di questi.
Le funzioni crittografiche (firma, cifratura) sono abbastanza semplici da utilizzare mentre per quelle di gestione dei certificati possono occorrere decine di minuti per un utente non del settore.
Ma guardiamo quello che firmaOK!gold può fare:

1- firmare digitalmente tutti i documenti elettronici. Nel caso in cui siano presenti differenti certificati sulla tua Smart Card è possibile selezionare la tipologia di firma da applicare (debole o forte).

2-verificare l'autenticità e l'integrità di qualsiasi firma digitale emessa da un certificatore accreditato.

3-cifrare i documenti elettronici, in modo che solo il destinatario prescelto sia in grado di leggerne il contenuto. Inoltre è possibile cifrare i file.

4-decifrare i documenti elettronici cifrati con la propria chiave pubblica.

5-applicare una marca temporale, che certifica in modo sicuro la data e l'ora in cui un documento è stato creato, trasmesso o archiviato.

6-verificare la validità di una marca temporale emessa da tutti i certificatori accreditati.

7-cambiare il pin della smart card.

8-in caso di blocco sboccare la smart card con il puk.

9-gestire un archivio certificati locale nel quale conservare i certificati usati più di frequente.

10-effettuare la ricerca di certificati nella sezione Registro Certificatore e salvare i certificati nell'Archivio.

Il prototipo di applicazione che ho sviluppato ha un interfaccia che può ricordare quella di firmaOK!gold e delle minori ma simili funzionalità; i dettagli verranno spiegati in seguito.


5.4 Applet

5.4.1 L'applet per la Firma Digitale

Una applet Java è una sorta di applicazione che un browser abilitato all'uso di Java può scaricare dalla rete ed eseguire. Il browser reperisce quindi i file di classe dalla rete ed esegue automaticamente l'applet, avvalendosi della macchina virtuale Java.
Ho strutturato questo prototipo di applicazione come una applet Java che è possibile eseguire direttamente dalla rete, senza bisogno di dover installare librerie necessarie ai vari processi crittografici.
L'applet di Firma Digitale può essere usata per verificare qualsiasi file *.p7m anche in calcolatori che non dispongono di software per farlo; è necessario solamente un collegamento alla rete per poter accedere alla pagina dove è presente l'applet ed eseguire le operazioni di verifica. E' infatti possibile (caratteristica presente anche in firmaOK!gold) verificare file senza avere una smart card collegata al sistema; questa cosa è corretta poichè per verificare dei file non è necessario accedere alle chiavi presenti nella smart card, è invece possibile reperire le informazioni per la verifica, le chiavi pubbliche, dallo stesso file da verificare (che contiene le info sul certificato del firmatario) e dalla rete (credibilità del certificato ed informazioni sulla revoca).
Per poter invece firmare dei file l'unica cosa necessaria è un smart card collegata al sistema (quindi un lettore di smart card opportunamente installato) ed un collegamento ad internet. Naturalmente si deve avere accesso alla smart card, cioè si deve conoscere il PIN per poter accedere alle chiavi presenti in essa. Collegandosi all'url in cui si trova l'Applet di Firma Digitale è possibile firmare file del proprio file system. Il processo di firma crea un nuovo file ``nomefile.estensionefile.p7m'' che contiene la firma, il file originale ed altre informazioni necessarie alla verifica quali certificato del firmatario.
Quindi, se volessimo inviare un file firmato, non è necessario inviare anche l'originale poichè l'implementazione PKCS#7 di S/MIME lo mantiene all'interno del file *.p7m.

5.4.2 La sicurezza nelle Applet

Siccome le applet sono studiate per essere caricate da un sito remoto e quindi eseguite localmente, la sicurezza diventa vitale. Se un utente abilita Java nel browser, quest'ultimo caricherà tutto il codice delle applet presente sulla pagina Web e lo eseguirà immediatamente.
L'utente non ha mai la possibilità di confermare o interrompere l'esecuzione delle singole applet. Per questo motivo, le applet a differenza delle applicazioni, sono limitate nelle operazioni che possono svolgere. La funzione di gestione della sicurezza delle applet lancia una eccezione di tipo Security Exception ogniqualvolta un'applet cerca di violare una delle regole di accesso.

Cosa possono fare quindi le applet?

Possono visualizzare immagini e riprodurre suoni, ricevere pressioni di tasti e clic del mouse dall'utente e ritrasmettere le immissioni dell'utente all'host da cui sono state caricate.

Le Applet vengono eseguite nella cosidetta ``SANDBOX''; questa è un contenitore che permette un minimo accesso alle risorse della macchina sulla quale l'applet sta girando. L'accesso ai file non è permesso e l'unica connessione di rete permessa è quella con il server dal quale l'applet viene caricata. Tutto ciò è una cosa positiva ai fini della sicurezza mentre non lo è se una applet ha bisogno di poter fare alcune operazioni cosiddette illegali.

E' per questo motivo che in Java 1.1 vennero introdotte le Applet Firmate. Se una Applet è firmata digitalmente gli vengono concessi tutti i privilegi, come se fosse una applicazione che viene eseguita localmente.

Vi è però un problema: cosa succede se una applet firmata, a cui vengono dati tutti i privilegi, il cui solo compito è stampare qualcosa, si comporta in modo non corretto, ad esempio accedendo alla e-mail o ai file di password? Non possiamo avere garanzia che questo non succeda.

Per questo Java 2 ha introdotto politiche di sicurezza che possono variare per ogni pezzo di codice. Esiste un file (java.policy) nel quale si possono inserire le varie politiche di sicurezza per ogni codice-url o per ogni firmatario. In seguito sono state introdotte le RSA signed appletts, che una volta firmate, danno tutti i permessi al codice che viene eseguito; una sorta di passo indietro verso Java 1.1.

Ho deciso di rendere la mia Applet di Firma Digitale una RSA-Signed Applet, per la necessità che l'applet ha di dover accedere, al file system, al dispositivo collegato al personal computer (smart card), ed alle librerie collegate. Per fare questo però ho dovuto creare una coppia di chiavi ed un certificato con il quale firmare l'Applet. Il certificato risulta chiaramente non verificato poichè questo non è rilasciato da una root CA Accreditata valida per il browser.
Questo è un altro motivo per il quale la mia applet è un Prototipo, ovvero una applicazione di esempio.
Richiedere un certificato ad una CA come Verisign o Thawte può costare dai 200 a 400 euro e per scopi dimostrativi ho preferito creane uno non verificato.
Inserendo quindi nel browser l'url della Applet per la Firma Digitale, questo ci informa che il contenuto della applet è non verificato poichè non è riuscito a risalire ad una autorità presente nella sua lista di CA accreditate. Rispondendo si alla domanda se siamo sicuri di accettare il contenuto firmato, diamo tutti i privilegi all'applicazione remota.
Questa potrebbe essere uno sviluppo futuro di una applicazione come firmaOK!gold.
Il fatto di avere scelto una Applet firmata fa si che questa sia disponibile ovunque e senza bisogno di installazione ed elimina la fase di verifica dell'integrità del software:
quando si apre firmaOK!gold il programma ricorda di verificare l'integrità di questo nel caso in cui un malintenzionato lo avesse modificato per farlo funzionare per i suoi scopi.

Il fatto di usare una applet firmata da una CA garantisce, certifica e rende sicura l'applicazione.

5.4.3 Il processo di creazione chiavi/certificato ed il processo di firma

La creazione delle chiavi e del certificato sono le due operazioni che devono essere compiute per poter firmare l'applet di firma digitale. Iniziamo con il generare la coppia di chiavi utilizzando keytool :

c: keytool -genkey -alias appletFirmataKey -keyalg RSA

Come si può notare abbiamo utilizzato RSA invece di DSA che è lo standard per la firma digitale.
Il tool richiede anche una password per accedere al keystore, ed alcune informazioni sul proprietario della chiave, come nome, organizzazione e luogo.
Adesso esportiamo il certificato dal proprio keystore e lo andiamo a salvare in un file:

c: keytool -export -alias appletFirmataKey -file certificateAppletFirmata.cer

Il passo seguente è stato quello di creare un file archivio sul quale inserire tutti i file *.class.
Si crea il file jar:

c: jar -cvf appletFirmata.jar *.class (tutti i file *.class del progetto)

infine si firma l'archivio java:

c: jarsigner appletFirmata.jar appletFirmataKey (alias).

Il programma richiederà la password per accedere al keystore e se tutto ha successo il processo di firma è completato. Abbiamo ottenuto un archivio java firmato attraverso un certificato che garantisce agli utenti la provenienza del codice che andranno ad eseguire.

{Le politiche di sicurezza dell'applet di firma digitale}
Java mette a disposizione il file ``java.policy'', un metodo per potere definire le politiche di sicurezza per un certo codice proveniente da un URL o per un codice firmato da una parte.
In questo file sono elencate le varie politiche di sicurezza.
Se la nostra applet non fosse firmata, (o anche non accettassimo il certificato) non potrebbe accedere al file system o al dispositivo crittografico connesso al computer.
Però anche dopo avere accettato il certificato non riusciamo a risolvere tutti i problemi:
l'applet non riesce a caricare le librerie necessarie per poter accedere alla smart card.
E' stato necessario fare editare all'applet in fase di runtime (poichè questa può accedere al file system ma non chiamare loadLybrary) il file java.policy inserendo le seguenti entries:

String policy ="permission java.security.AllPermission;"+
                       "permission java.lang.RuntimePermission
                       "loadLibrary.pkcs11wrapper""+
                       ";permission java.util.PropertyPermission
                       "user.dir", "read,write";};"

                       "grant signedBy "iacopo" { " +
                       "permission java.security.AllPermission;"+
                       "permission java.lang.RuntimePermission
                       "loadLibrary.pkcs11wrapper""+
                       ";permission java.util.PropertyPermission
                       "user.dir", "read,write";};";

Si può notare che ho inserito RunTimePermission che da il permesso di caricare dinamicamente le librerie (Cryptoky) necessarie per poter accedere al dispositivo crittografico.
L'applet dopo aver editato il file aggiorna le politiche di sicurezza:

                       setJavaPolicyFile(policy);
                       Policy newPolicy = Policy.getPolicy();
                       newPolicy.refresh();

5.5 Multipiattaforma, Interoperabile e Compatibile

Il nostro prototipo è un buon esempio di applicazione che può essere usata quando non abbiamo a disposizione i programmi che solitamente usiamo per le nostre operazioni crittografiche. E' chiaro che una applicazione che gira in locale nel ``nostro'' caro personal computer sarà la ``nostra'' scelta quando ci troviamo nella nostra solita postazione di lavoro, ma pensiamo ad esempio di trovarci in un nuovo personal computer dotato di accesso ad internet che però non dispone di software come firmaOK!gold. Conoscendo l'url della nostra applet possiamo eseguire le operazioni di firma e verifica senza dover installare alcuna applicazione; questo vale per sistemi non Windows ma anche per dispositivi diversi da Personal Computer, come possono essere i palmari o addirittura i cellulari di ultima generazione.

Un'altra caratteristica che potrebbe rendere accessibile l'applet ad un sempre più grande numero di utenti è l'interoperabilità del prototipo con i vari dispositivi hardware disponibili nel mercato;
si! ho detto potrebbe perchè per mancanza di dispositivi hardware non è stato possibile implementare questa caratteristica se non per il lettore e la smart card che ho in dotazione.

Come abbiamo già detto l'implementazione di Cryptoky mette a disposizione una interfaccia in grado di comunicare con i più disparati hardware; le librerie IAIK comunicano con il dispositivo fisico utilizzando delle librerie collegate dinamicamente o staticamente; queste vengono fornite dal produttore della smart card e sono necessarie per comunicare con il sistema operativo delle stesse: quello che in futuro sarebbe quindi possibile implementare nella nostra applet è solamente un supporto a più smart card semplicemente chiedendo all'utente di scegliere tra una serie di dispositivi; effettuata la scelta l'applet sarebbe in grado di scegliere le opportune librerie (dll) da caricare.

Abbiamo a disposizione un prototipo di Applicazione per la Firma Digitale con le seguenti caratteristiche:

- multipiattaforma: può girare sui più disparati sistemi, grazie all'utilizzo del linguaggio java e grazie alla tecnologia delle Applet che la rendono presente ovunque vi è un collegamento alla rete.
- interoperabile e compatibile: può supportare un grande numero di dispositivi crittografici sicuri come le smart card semplicemente inserendo nuove librerie fornite dai costruttori.
- funzionale: esegue le operazioni di firma e verifica di file
- semplice: una caratteristica ``banale ma necessaria''; è la base di ogni buona applicazione che viene creata per raggiungere in modo veloce il suo scopo.
- sicura: viene firmata con un certificato che ne attesta la provenienza e certifica il codice che viene eseguito sul nostro calcolatore.

5.5.1 Riflessione sul problema di Certificazione

Nei vari browser sono inseriti i certificati delle varie Autorità internazionali che ci permettono di verificare siti web o applicazioni (come applet) che altrimenti potrebbero essere pericolose.
In italia come ho già detto non esiste un meccanismo gerarchico di verifica dei Certificati; le autorità Italiane non fanno capo ad altre Autorità Internazionali. L'italia ha un proprio modo di operare: vi sono i vari enti certificatori Italiani che rilasciano certificati a privati e non.
I certificati dei vari certificatori sono self signed e fanno riferimento alla lista di CA pubblicata nella gazzetta ufficiale e firmata da Livio Zoffoli, presidente del Centro Nazionale Informatica Pubbliche Amministrazioni.
Ancora non vi è un modo per poter disporre di browser con incorporati dei Certificati di Enti Italiani, a meno che non si prenda da una fonte sicura il certificato di un ente, ad esempio quello di Postecom, e lo si inserisca manualmente sul browser; questa operazione è a dir poco impensabile per un utente qualunque.

Anche se l'Italia è stato il primo paese ad avere introdotto la Firma Digitale nella propria legislazione ed ad avere superato la soglia del milione di titolari, questa è una cosa ancora lontana da poter essere usata dagli utenti e rimane principalmente legata al settore burocratico/amministrativo. Credo che dovremo aspettare ancora un po' prima di poter osservare la Firma Digitale come uno strumento presente nelle comuni operazioni dei navigatori.

5.6 Gli algoritmi di Firma e Verifica

5.6.1 Firma in generale

Iniziamo analizzando il processo di firma di un file.
Quello che andremo a guardare è un classico uso di PKCS#11:
per prima cosa è necessario settare ed inizializzare i parametri dell'applicazione, ovvero settare le corrette librerie ed inizializzare il modulo che si occupa della comunicazione con i dispositivi crittografici.

Module module = Module.getInstance("libreria.dll");

Naturalmente si deve rimpiazzare ``libreria.dll'' con il nome del modulo PKCS#11 dell'hardware che abbiamo a disposizione; utilizzando una smart card GEMPLUS GEMGATE 32K il nome del modulo (librerie proprietarie) è ``gclib.dll''.

Inizializziamo il modulo:

module.initialize (new DefaultInitializeArgs());

Andiamo a guardare tutti gli slot nei quali sono presenti smart card e ne selezioniamo uno (nel nostro caso è presente solamente una smart card, quindi selezioneremo la prima):

Slot[] slotsWithToken =
module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT);
Token token = slotsWithToken[0].getToken();

Adesso dobbiamo aprire una sessione nel token che abbiamo selezionato; una sessione di sola lettura non ci permetterà di scrivere nel token, ma ci permetterà di effettuare operazioni crittografiche come firmare file.

Nel nostro caso una sessione di sola lettura è ottima poichè non vogliamo cancellare o modificare i dati della smart card, ovvero chiavi e certificati. Il tipo di sessione SERIAL_SESSION è l'unico tipo supportato dalle librerie.

Session session = token.openSession(
Token.SessionType.SERIAL_SESSION,
Token.SessionReadWriteBehavior.RO_SESSION,
null, null);

Prima di poter effettuare operazioni crittografiche, quindi prima di poter accedere alle chiavi utilizzate per firmare, è necessario autenticare l'utente che utilizza il dispositivo tramite l'inserimento di un codice PIN.

Il codice PIN è un numero a sei cifre segreto che permette di rendere sicura la smart card anche in caso di smarrimento; non disporre di questo requisito di sicurezza è un problema nel caso in cui un utente malintenzionato, che viene in possesso di un dispositivo altrui, firmi dei dati; questi divengono riconducibili legalmente al proprietario della smart card.

if (tokInfo.isLoginRequired())
{
// check, if the token has own means to authenticate the user;
// e.g. a PIN-pad on the reader

if (tokInfo.isProtectedAuthenticationPath())
{

System.out.println("Please enter the user PIN at
the PIN-pad of your reader.");
session.login(Session.UserType.USER, null);

// the token prompts the PIN by other means; e.g. PIN-pad
}
else
{
//richiesta inserimento pin

String userPINString = JOptionPane.showInputDialog(null,"Inserisci user-PIN:");
if(userPINString == null)
{
return;
}
session.login(Session.UserType.USER, userPINString.toCharArray());
}
}

 

Come possiamo vedere si controlla se il dispositivo richiede l'autenticazione e, se questa è necessaria si controlla a sua volta se il dispositivo ha un suo proprio metodo di autenticazione, come un tastierino per l'insermento del PIN o come un impronta digitale o se invece il pin viene richiesto dall'applicazione: la nostra applet mostra all'utente una finestra di input che permette l'inserimento del codice segreto.

Se vogliamo firmare dei dati si deve cercare una chiave all'interno del token; questa chiave è una chiave privata di tipo RSAPrivateKey

// creiamo una RSA private key per la firma
RSAPrivateKey searchTemplate = new RSAPrivateKey();
searchTemplate.getSign().setBooleanValue(Boolean.TRUE);
// cerchiamo la chiave
session.findObjectsInit(searchTemplate);
Object[] matchingKeys;
RSAPrivateKey signatureKey;
if ((matchingKeys = session.findObjects(1)).length > 0)
{
signatureKey = (RSAPrivateKey) matchingKeys[0]);
} else
{
// non abbiamo trovato la chiave
}
// completiamo l'operazione di ricerca
session.findObjectsFinal();

Si possono anche specificare dei particolari attributi per prendere una chiave specifica, (una etichetta o un ID).

Se vogliamo firmare dei dati ecco quali sono i passi base che devono essere compiuti:

byte[] data = ...;
// seleziona il meccanismo di firma (controllare che il token lo supporti)
Mechanism signatureMechanism = Mechanism.SHA1_RSA_PKCS;
// inizializzazione per la firma
session.signInit(signatureMechanism, signatureKey);
byte[] signatureValue = session.sign(data);

Il risultato è una RSA signature in accordo con PKCS#1.
Quanto sopra illustrato è ciò che si deve fare per firmare dei file.

Il prototipo di applicazione che ho sviluppato, anche se in generale compie gli stessi passi, esegue delle operazioni un po' diverse da quelle sopra esaminate e da come risultato un file in formato S/MIME PKCS#7 che come sappiamo è lo standard per la firma digitale.

5.6.2 Il processo di Firma nella nostra Applet

Andiamo ad analizzare i dettagli del processo di firma del nostro prototipo.
Come in precedenza si settano le librerie e si inizializza il modulo:
la cosa interessante è che non è necessario che le librerie siano nel file system poichè l'applet scarica la dll direttamente dall'url al quale si trova.

URL pkcsDll = new URL(homeDirectory+"pkcs11wrapper.dll");
InputStream is = pkcsDll.openStream();
File dll = new File(dirPkcs11Dll+File.separator+"pkcs11wrapper.dll");
FileOutputStream fos = new FileOutputStream(dll);
int intRead;
while((intRead=is.read()) != -1)
{
fos.write(intRead);
}
is.close();
fos.close();
AppletFirmata.inizializeSmartCard(AppletFirmata.libFile);
//inizializzazione di una sessione READ_ONLY
//e login tramite inserimento di codice PIN
[....]

L'operazione che segue è la ricerca della chiave privata RSA all'interno della smart card; per fare questo però utilizziamo un nuovo metodo: selectKeyAndCertificate.
Questo metodo seleziona all'interno della smart card tutte le chiavi e certificati e, se sono presenti, chiede all'utente quale di questi utilizzare:
nel caso del kit di Postecom l'applet chiede se utilizzare una firma forte o debole (la firma forte equivale alla firma elettronica qualificata).

RSAPrivateKey privateSignatureKeyTemplate = new RSAPrivateKey();
privateSignatureKeyTemplate.getSign().setBooleanValue(Boolean.TRUE);
KeyAndCertificate selectedSignatureKeyAndCertificate =
selectKeyAndCertificate(session, privateSignatureKeyTemplate,
null,new BufferedReader(new InputStreamReader(System.in)) );
if (selectedSignatureKeyAndCertificate == null)
{
AppletFirmata.manageError("We have no signature
key to proceed. Finished");
System.exit(0);
session.logout();
}
PrivateKey selectedSignatureKey =
(PrivateKey) selectedSignatureKeyAndCertificate.getKey();
X509PublicKeyCertificate pkcs11SignerCertificate =
selectedSignatureKeyAndCertificate.getCertificate();
X509Certificate signerCertificate =
(pkcs11SignerCertificate != null)?
new X509Certificate(pkcs11SignerCertificate.getValue().getByteArrayValue())
: null;

Dopo avere creato la chiave privata ed il certificato per la firma si accede in lettura al file selezionato; vengono creati due array, uno per il contenuto ed uno per il valore hash del file.
L'operazione di message digest viene effettuata esternamente poichè non tutti i dispositivi crittografici la mettono a disposizione.

InputStream dataInputStream =
new FileInputStream(AppletFirmata.getFile());
// we do digesting outside the card, because some
// cards do not support on-card hashing
MessageDigest digestEngine = MessageDigest.getInstance("SHA-1");
// we buffer the content to have it after hashing
// for the PKCS#7 content
ByteArrayOutputStream contentBuffer = new ByteArrayOutputStream();
byte[] dataBuffer = new byte[1024];
byte[] helpBuffer;
int bytesRead;
// feed all data from the input stream to the message digest
while ((bytesRead = dataInputStream.read(dataBuffer)) >= 0)
{
// hash the data
digestEngine.update(dataBuffer, 0, bytesRead);
// and buffer the data
contentBuffer.write(dataBuffer, 0, bytesRead);
}
byte[] contentHash = digestEngine.digest();
contentBuffer.close();

Viene poi creata la struttura SignedData; questa rappresenta l'implementazione del PKCS#7 content-type SignedData. Questa operazione è necessaria per ottenere un file firmato in formato p7m. Come si può notare, creiamo la struttura passando al costruttore l'array che contiene il file e SignedData.IMPLICIT; questo gli indica che la struttura è implicita, ovvero che la firma, il file originale ed il certificato saranno contenuti all'interno dello stesso file *.p7m una volta che l'operazione sarà completa.
E' per questo motivo che dal file firmato possiamo ottenere l'originale.
Si settano poi alcuni attributi per la firma, come contentType, messageDigest e signingTime.
Per la firma si inizializza il meccanismo RSA_PKCS.

begin{lstlisting}
// create the SignedData
//implicita = in un unico file che contiene
// file firmato e data
SignedData signedData =
new SignedData(contentBuffer.toByteArray(), SignedData.IMPLICIT);
// set the certificates
signedData.setCertificates
(new X509Certificate[] { signerCertificate });

// create a new SignerInfo
SignerInfo signerInfo =
new SignerInfo(new IssuerAndSerialNumber(signerCertificate)
, AlgorithmID.sha1, null);
// define the authenticated attributes
iaik.asn1.structures.Attribute[] authenticatedAttributes = {
new Attribute(ObjectID.contentType,
new ASN1Object[] {ObjectID.pkcs7_data}),
new Attribute(ObjectID.signingTime,
new ASN1Object[] {new ChoiceOfTime().toASN1Object()}),
new Attribute(ObjectID.messageDigest,
new ASN1Object[] {new OCTET_STRING(contentHash)})
};
// set the authenticated attributes
signerInfo.setAuthenticatedAttributes(authenticatedAttributes);

// encode the authenticated attributes,
// which is the data that we must sign
byte[] toBeSigned =
DerCoder.encode(ASN.createSetOf(authenticatedAttributes, true));

// we do digesting outside the card,
//because some cards do not support on-card hashing
// we can use the digest engine from above
byte[] hashToBeSigned = digestEngine.digest(toBeSigned);
// according to PKCS#11 building
//the DigestInfo structure must be done off-card
DigestInfo digestInfoEngine =
new DigestInfo(AlgorithmID.sha1, hashToBeSigned);

byte[] toBeEncrypted = digestInfoEngine.toByteArray();
// initialize for signing
session.signInit(Mechanism.RSA_PKCS, selectedSignatureKey);
// sign the data to be signed
byte[] signatureValue = session.sign(toBeEncrypted);
// set the signature value in the signer info
signerInfo.setEncryptedDigest(signatureValue);
// and add the signer info object to the PKCS#7 signed data object
signedData.addSignerInfo(signerInfo);
end{lstlisting}

L'ultima operazione è il salvataggio del file firmato sul file system; l'applet richiede all'utente il nome del nuovo file p7m.
Il file viene codificato con BASE64.index{BASE64}
L'encoding Base64 è la codifica utilizzata da MIME per trasmettere dati non-testuali sopra un canale di comunicazione testuale.
Infine si esegue il logout che determina la fine della sessione/comunicazione con il dispositivo.

JFileChooser choose = new JFileChooser();
choose.setCurrentDirectory(
new File("C:Documents and SettingsiacopoDesktop"));
choose.setSelectedFile(new File(AppletFirmata.getFile()+".p7m"));
int result = choose.showSaveDialog(list);
if(result == JFileChooser.APPROVE_OPTION)
{
File signedFile = choose.getSelectedFile();
OutputStream signatureOutput =
new FileOutputStream(signedFile);
ContentInfoStream cis = new ContentInfoStream(signedData);
BufferedOutputStream bos =
new BufferedOutputStream(signatureOutput);
Base64OutputStream b64Out = new Base64OutputStream(bos);
cis.writeTo(b64Out);
b64Out.close();
JOptionPane.showMessageDialog(list,"File Firmato con successo!");
session.logout();
}

5.6.3 Il processo di Verifica

Illustriamo adesso il processo di verifica:

Supponiamo di avere un file S/MIME PKCS#7 con estensione p7m.
Vogliamo verificare la validità della firma in tutti i suoi aspetti, ovvero:

1- verificare la validità della firma apposta al file
2- verificare la credibilità del Certificatore che ha rilasciato la chiave pubblica e privata al firmatario
3- verificare le informazioni sulla revoca del certificato

 

Andiamo ad analizzare la prima fase; questa è la parte più importante del processo: si verifica con la chiave pubblica (presente nel certificato rilasciato da una Autorità di Certificazione) la firma apposta sul file.

Il metodo che si occupa di questo è verificaFilePKCS7Frame(File f).
Il metodo prende in input il file con estensione p7m e ritorna un'eccezione se la verifica fallisce.
Viene aperto un inputStream al file firmato che ci permette di leggere il contenuto.
L'inputStream è di tipo ANS1InputStream; questa è una classe filtro che offre una codifica Standard e ci permette di leggere differenti formati (come DER codificato ANS1, Base64 codificato ANS1 ecc..).
L'oggetto ANS1InputStream diviene il parametro del costruttore dell'oggetto ContentInfoStream:
questa classe rappresenta l'implementazione del tipo PKCS#7 ContentType. Viene infatti utilizzata per determinare che tipo di trasformazioni crittografiche sono state applicate ai dati (data, signedData, envelopedData, signedAndEnvelopedData, digestedData, encryptedData).
Con un costrutto ``if'' controlliamo se il file è di tipo SignedData, ovvero se è un file firmato.

InputStream encodedStream = new FileInputStream(f);

ASN1InputStream asn1 = new ASN1InputStream(encodedStream);
ContentInfoStream cis = new ContentInfoStream(asn1);
SignedDataStream signedData;
// ask for the content type:
if (cis.getContentType().equals(ObjectID.cms_signedData))
{
// get the SignedData content:
signedData = (SignedDataStream)cis.getContent();
// proceed as usual for reading the data,
//getting the SignerInfos and
// verifying the signatures
}
else
{
AppletFirmata.manageError("Expected
content type SignedData!");
throw new CMSParsingException("Error!
Expected content type SignedData!");
}

L'operazione successiva è quella di memorizzare il contenuto del file originale (non firmato) in un array di byte. Questo servirà poi per poter salvare il file originale sul file system avendo a disposizione solamente il file p7m.

InputStream contentStream = signedData.getInputStream();
byte[] read = new byte[10240];
int byteRead;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((byteRead = contentStream.read(read)) > 0)
{
baos.write(read,0,byteRead);
//System.out.write(read,0,byteRead);
}

Siamo giunti alla vera e propria verifica: questa è una operazione molto semplice poichè viene fatta automaticamente dai metodi messi a disposizione da IAIK.

Dopo avere recuperato le informazioni sul firmatario si effettua la verifica; se questa ha successo si visualizza il certificato; questo viene mostrato in una nuova finestra che mette a disposizione le operazioni di salvataggio del file originale, di verifica di Credibilità del Certificatore e di Informazioni sulla Revoca.
Se la verifica non ha successo il metodo lancia una eccezione.

SignerInfo[] signerInfos = signedData.getSignerInfos();
for (int i=0; i < signerInfos.length; i++)
{
try
{
// verify the signature for SignerInfo at index
X509Certificate signerCertificate = signedData.verify(i);
CertificateFactory factory = CertificateFactory.getInstance("X.509");
CertFrame dialog = new CertFrame
(null,"Firma corretta",signerCertificate,
signerCertificate.getIssuerDN().toString(),
signerCertificate.getFingerprint(),f,byteArrayFileTemp);
try
{
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
SwingUtilities.updateComponentTreeUI(dialog);
}
catch(Exception e)
{
AppletFirmata.manageError("Verification failed:
unable to open verification Frame!");
e.printStackTrace();
}
dialog.setSize(600,470);
dialog.setResizable(false);
dialog.setVisible(true);
}
catch (SignatureException ex)
{
// if the signature is not OK a SignatureException is thrown
AppletFirmata.manageError("Signature ERROR from signer with certificate: "+signedData.getCertificate(signerInfos[i].getIssuerAndSerialNumber()));
ex.printStackTrace();
}
}

Andiamo ora a guardare come viene effettuata la seconda parte della verifica, ovvero la verifica della credibilità del certificato che viene rilasciato all'utente da parte di un organismo Certificatore.
Quello che dobbiamo controllare è che chi rilascia il certificato sia realmente il Certificatore Accreditato e non qualcuno che si spaccia per esso, ad esempio mettendo un nome falso identico a quello del Certificatore.
Come sappiamo un certificato non è altro che delle informazioni cifrate con la chiave privata di una CA; per la verifica di credibilità si deve reperire la chiave pubblica di questa CA e con questa effettuare la verifica.
Per fare questo la prima operazione che la nostra Applet esegue è il download di una lista di Enti Certificatori che il Centro Nazionale per l'informatica nella Pubblica Amministrazione (CNIPA) rende disponibile on-line.
Questo elenco viene firmato dal Dott. Livio Zoffoli, presidente del CNIPA ed aggiornato periodicamente.
Ecco il codice che scarica l'elenco delle CA, verifica la firma apposta dal Dott. Zoffoli controllando che il fingerprint del certificato di Zoffoli corrisponda con quello rilasciato nella Gazzetta Ufficiale (di cui l'applet è a conoscenza) e lo decomprime.

URL listaSource = new URL(
"http://www.cnipa.gov.it/site/_files/lista%20dei%20certificati.html");
String nomeLista = AppletFirmata.getNameListCertFromURL(listaSource);
//prendo nome file lista da html
File listaCertSigned = new File(nomeLista);
System.out.println("Lista certificati: "+nomeLista);
System.out.println("Download :"+listaCertSigned.getAbsolutePath());
URL urlLista = new
URL("http://www.cnipa.gov.it/site/_files/"+nomeLista);
InputStream in = urlLista.openStream();
FileOutputStream fos = new FileOutputStream(listaCertSigned);
int a;
while((a=in.read())!=-1)
{
fos.write(a);
}
fos.close();
in.close();

byte[] fileList = AppletFirmata.verificaFilePKCS7(listaCertSigned);
if(fileList == null)
{
AppletFirmata.manageError("Certificate Not Valid!");
container.setCursor
(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
return;
}
nomeLista=nomeLista.string(0,nomeLista.length()-4);
File fileZip = new File(nomeLista);
System.out.println("fileZip: "+fileZip.toString());
FileOutputStream fosZip = new FileOutputStream(fileZip);
fosZip.write(fileList);
fosZip.close();
System.out.println("ZIP:"+fileZip.toString());

//3:decomprimo la lista
System.out.println(ZipUtils.ZipToXml(nomeLista,
nomeLista.string(0,nomeLista.length()-4)));
nomeLista=nomeLista.string(0,nomeLista.length()-4);
System.out.println("Nome file lista cert :"+nomeLista+"");

end{lstlisting}
Andiamo a vedere in dettaglio il metodo che effettua la verifica:
stiamo parlando del metodo verificaFilePKCS7(listaCertSigned).
Questo metodo dopo avere verificato la firma controlla il fingerprint del Dott. Zoffoli chiamando il seguente metodo:
begin{lstlisting}
private static boolean checkZoffoliFingerPrint(X509Certificate cert)
{
String zoffoli =
"F7:58:2B:22:38:91:32:58:A5:F3:4F:FF:A0:6A:5A:26:89:97:73:2B";
String certString = cert.toString();
System.out.println("Certificato: "+certString);
if(certString.contains(zoffoli))
{
return true;
}else
{
return false;
}
}

Si va a guardare se il certificato del Dott. Zoffoli contiene la stringa ``zoffoli'' che rappresenta il suo fingerprint.
Dopo avere decompresso la lista il metodo di verifica accede alla cartella (all'interno della lista) che porta il nome dell'Ente Certificatore che ha rilasciato il certificato.
Se la cartella viene trovata si prosegue alla ricerca di un certificato che abbia lo stesso fingerprint dell'ISSUER (chi ha rilasciato il certificato). Se vi è una corrispondenza tra i valori dei fingerprint la verifica di Credibilità ha successo.

Dopo avere decompresso la lista il metodo di verifica accede alla cartella dei certificati e li importa in un array. In seguito si sceglierà la cartella avente il nome dell'Issuer per andare a cercare il certificato da usare per la verifica. Se la cartella viene trovata si prosegue alla ricerca di un certificato che abbia lo stesso identificativo chiave autorità dell'ISSUER (chi ha rilasciato il certificato).
Dopo avere identificato il certificato della CA interessata, ne prendiamo la chiave pubblica e la utilizziamo per verificare il certificato del presunto Issuer che è contenuto all'interno della busta PKCS#7. Se la verifica ha successo significa che la chiave privata utilizzata per firmare il certificato (per firmare info e chiave pubblica del firmatario) contenuto all'interno della busta PKCS#7 corrisponde alla relativa pubblica ottenuta dal certificato all'interno della lista e quindi che il certificatore che ha rilasciato il certificato è accreditato.
Se il metodo itshape verify non lancia una eccezione la verifica di credibilità termina con successo.

X509Certificate certIssuerFromList = lista.findCertificate();
boolean certVerified;
try
{
certificateTarget.verify(certIssuerFromList.getPublicKey());
certVerified = true;
}
catch(Exception ex)
{
certVerified = false;
}
if(certIssuerFromList != null && certVerified == true)
{
JOptionPane.showMessageDialog(null,"Certificato Valido!","Certificato Verificato",JOptionPane.INFORMATION_MESSAGE);
rowData[0][1] = "Verificato";
scrollVerificaResult.repaint();
scrollVerificaResult.repaint();*/
System.out.println("Certificato valido!");
int result = JOptionPane.showConfirmDialog(null,"Visualizzare il certificato del Presidente del CNIPA?","Root Certificate",JOptionPane.YES_NO_OPTION);

if(result == JOptionPane.YES_OPTION)
{
cert.setVisible(true);
}
else
{
}
verificaCertificato.setEnabled(true);
progress.setValue(0);
labelProgress.setText("Progresso verifica");
certContentPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
return;
}
else
{
AppletFirmata.manageError("Certificate Not Valid!");
System.out.println("N1 valido");
certContentPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
verificaCertificato.setEnabled(true);
progress.setValue(0);
labelProgress.setText("Progresso verifica");
return;
}

Il metodo findCertificate controlla all'interno della lista alla ricerca di un certificato che abbia lo stesso ``jectDN'' e la stessa estensione ``identificativo chiave autorità'' del certificato che dobbiamo verificare. Se lo trova viene ritornato.

public X509Certificate findCertificate() throws Exception
{
int i=0;
System.out.println("CERT AUTH: "+certificateAuthority);
System.out.println("EXT "+ext.toString());
while(certList[i]!=null && i < certList.length)
{
System.out.println("JECT: "+certList[i].getjectDN().toString()+certList[i].getExtension(new ObjectID("2.5.29.35")));

if(certList[i].getjectDN().toString().equals(certificateAuthority) && certList[i].getExtension(new ObjectID("2.5.29.35")).toString().equals(ext.toString()) )
{
System.out.println("Certificato "+certList[i].getjectDN().toString()+" trovato!");
return certList[i];
}
i++;
}
return null;

}

 

 

L'importanza della Verifica di Credibilità

Ipotizziamo che un utente malintenzionato crei un certificato che ha il nome uguale a quello di un ceritificatore accreditato (per esempio Postecom CA1) e con questo firmi un file od un altro certificato.
Quando andiamo a verificare questa firma il nostro software di verifica ci dirà che il certificato è stato firmato da Postecom CA1. Potremmo pensare che sia valido anche se in realtà non lo è.

Per questo motivo il ``prototipo'' di applicazione scarica la lista degli Enti Certificatori da un elenco messo a disposizione dal CNIPA, prende il certificato della CA da controllare e lo cerca all'interno di questa lista per verificare con la chiave pubblica che questo non sia stato opportunamente falsificato.

Una cosa simile a quella appena descritta è il bug di cui soffriva il software firma e cifra (bug di Arsen Lupin). L'errore era dovuto al fatto che nella busta PKCS#7 veniva inserito anche il certificato root della CA interessata; il software si accontentava di quel certificato (senza scaricarlo o reperirlo in maniera sicura) e la verifica aveva successo.

Verifica delle Informazioni di Revoca del Certificato

L'ultima parte della verifica è il controllo delle informazioni di revoca di un certificato. Come abbiamo già detto, se un certificato perde la sua validità prima della data di scadenza questo viene inserito in delle Certificate Revocation List. Dobbiamo essere quindi sicuri che il certificato che vogliamo verificare ``non sia presente'' in queste liste.

Per adesso la legge impone che ogni certificatore metta a disposizione una CRL accessibile on-line.
In accordo a X509 versione 3, lo standard per i certificati, gli enti certificatori hanno introdotto
una estensione X509 chiamata ``CRL Distribution Point'' (Punto di distribuzione delle CRL), che consiste in un indirizzo url ``http'' o ``ldap'' al quale vengono pubblicate le liste di revoca.
L'applet scarica il file ``*.crl'' dal punto di distribuzione del Certificatore che ha rilasciato il certificato che vogliamo verificare, importa la lista di certificati revocati e effettua la ricerca; se il certificato viene trovato la verifica fallisce: il certificato ha perso la sua validità.
Andiamo a vedere quali sono i passi che l'applet deve eseguire:

estrarre dal certificato il punto di distribuzione

//si estrae l'estensione Punto di distribuzione
CRLDistributionPoints ext = (CRLDistributionPoints)
certificateTarget.getExtension(new ObjectID("2.5.29.31"));
System.out.println("DISTRIBUTION POINT: "+ext.toString() );
String[] res = ext.toString().split(": ");
String distributionPoint = res[2];
System.out.println("Punto di distribuzione: "+distributionPoint);
end{lstlisting}

controllare LDAP o HTTP ed importare certificati Revocati (*.crl)

begin{lstlisting}
//si controlla se l'URL è LDAP o HTTP
if(distributionPoint.contains("ldap"))
{
System.out.println("Verifica REVOCA tramite LDAP");
LDAPUrl ldapUrl = new LDAPUrl(distributionPoint);
LDAPfunction ldap =
new LDAPfunction(ldapUrl.getHost(),389,"","",distributionPoint);
byte[] data = ldap.connection();
File fileCrl = new File("crl.crl");
FileOutputStream fileOut = new FileOutputStream(fileCrl);
fileOut.write(data);
}else
{
System.out.println("Verifica REVOCA tramite HTTP");
downloadCRL(new URL(distributionPoint),"crl.crl");
}

/* metodo donwloadCRL
private void downloadCRL(URL crlURL,String nomeCRL)
{
File fileCRL = new File(nomeCRL);
InputStream is = crlURL.openStream();
FileOutputStream fos = new FileOutputStream(fileCRL);
int a;
while((a=is.read())!=-1)
{
fos.write(a);
}
fos.close();
is.close();
}
*/

controllare che il certificato che vogliamo verificare non sia presente nella CRL.

if(isRevoked(certificateTarget,new File("crl.crl")))
{
AppletFirmata.manageError("Certificate Not Valid!");
certContentPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
System.out.println("Certificato Revocato");
verificaCertificato.setEnabled(true);
progress.setValue(0);
return;
}
else
{
rowData[1][1] = "Verificato";
scrollVerificaResult.repaint();
}

/* metodo isRevoked
private boolean isRevoked(X509Certificate cert,File crlFile)
{

FileInputStream inStream = new FileInputStream(crlFile);
X509CRL crl = new X509CRL(inStream);
inStream.close();
if(crl.isRevoked(cert))
{
return true;
}
else
{
return false;
}
}
*/

Capitolo 6

Manuale Utente

6.1 Introduzione

Con questo prototipo di Applet per la Firma Digitale puoi firmare e verificare i vari documenti, rispettando gli attuali standard Italiani per la firma digitale.
L'applet si integra con la maggior parte delle piattaforme e non ha bisogno di installazione poichè viene scaricata direttamente dalla rete. Basta avere un lettore di smart card funzionate collegato al proprio Personal Computer per poter accedere alle informazioni presenti nel dispositivo ed utilizzarle per la firma digitale.

Ecco cosa l'applicazione è in grado di fare:

- Firmare digitalmente i vari documenti elettronici. Permette di scegliere il tipo di firma a seconda dei certificati presenti nella smart card. E' possibile selezionare le due tipologie di firma: forte e leggera.
- Verificare l'autenticità e l'integrità di qualsiasi firma digitale emessa da un certificatore accreditato, ovvero:

1- verificare la validità della firma apposta su di un file
2- verificare la credibilità del certificato
3- verificare le informazioni sulla revoca

6.2 Requisiti

Affinchè l'applet funzioni correttamente è necessario un lettore smart card installato nel sistema; la smart card è necessaria quando si vuole firmare dei file; l'applicazione infatti ha bisogno dei dati presenti all'interno della smart card per eseguire la firma.

Il Java plug-in installato nel sistema per poter eseguire l'applet.
Il Java plug-in è disponibile insieme al JDK o JRE oppure separatamente in un file dimensione di 5 / 6 MB.
E' necessario installarlo una volta per fare in modo che i vari browser lo utilizzino per il corretto funzionamento delle Java Applets.

6.3 Accedere all'Applet

Per poter caricare l'Applet è necessario aprire il browser ed inserire l'indirizzo al quale l'Applet risiede. Per scopi dimostrativi inseriremo l'indirizzo del server locale, sul quale è installato un server Web. Per caricare l'Applet dovremo accedere alla pagina Html che la contiene:

URL=http://127.0.0.1/tesi/AppletFirmata.html


6.3.1 La sicurezza

Dopo avere inserito correttamente l'indirizzo dell'applicazione il browser visualizzerà un avviso di protezione poichè si sta eseguendo del codice che è stato firmato da una parte che non può essere verificata; per poter eseguire l'applet è necessario Considerare Attendibile il Certificato di Protezione.

Per fini dimostrativi non è stato richiesto un Certificato ad una CA internazionale, ma in un utilizzo reale di questa applicazione, la firma con certificato rende sicuro il codice che verrà eseguito.

6.4 Selezionare ed Eliminare i Files

Prima di poter eseguire le operazioni di firma e/o verifica si deve selezionare il file sul quale effettuare tali operazioni.
Per selezionare un file è necessario:

1- cliccare sul bottone aggiungi
2- nella finestra select navigare fino alla cartella in cui si trova il file
3- selezionare il file
4- cliccare sul bottone select

Dopo avere selezionato il file questo viene inserito nell'area di testo sottostante.

Questa area è una lista che può contenere più file. In caso di errore nella selezione è possibile eliminare il file dalla area di testo semplicemente selezionandolo e cliccando sul bottone Rimuovi.

6.5 Firma

L'applet permette di applicare due tipi di firma: firma forte e firma debole. Solamente la prima ha valore legale, e ad esempio può essere usata per concludere un contratto.
Ecco le operazioni che devono essere effettuate per firmare un file:

1-selezionare il file
2-cliccare sul bottone firma




3-inserire il codice PIN segreto



4- selezionare la tipologia di firma (forte o debole)


5- assegnare un nome al file firmato
6- cliccare su save


L'applicativo restituisce un messaggio se la firma viene effettuata con successo. Il file viene salvato aggiungendo l'estensione p7m.


6.6 Verifica

La verifica di una firma consiste in tre passi:

1-verifica della firma apposta ad un file (verifica di integrità)
2-verifica della credibilità di un certificato
3-verifica delle informazioni di revoca

Per verificare un file l'utente deve:

1- selezionare il file firmato (p7m)
2- cliccare sul pulsante verifica

Questa è la verifica di integrità della firma apposta su di un file; con questa andiamo a controllare che un file non sia stato modificato e/o alterato. Se questa verifica ha successo l'Applet mostra una finestra che visualizza il certificato del firmatario. La finestra presenta due pulsanti: ``save'' e ``verifica''.

1- Cliccando su Salva documento è possibile estrarre dal file firmato il file originale e salvarlo sul file system del nostro personal computer.


2- Cliccando su Verifica Certificato vengono effettuare le seguenti verifiche:

- verifica di Credibilità: si controlla che il Certificatore che ha rilasciato il certificato a colui che ha firmato il file sia effettivamente quello dichiarato (corrisponda ad uno dei Certificatori Accreditati)
- verifica Informazioni di Revoca: si controlla che il certificato non sia stato sospeso o revocato

In seguito alla pressione del bottone ``Verifica certificato'' l'applet mostra i risultati con l'esito della verifica nella tabella sul fondo della finestra.

Se la verifica non ha successo viene mostrato un messaggio di errore.


Username:
Password:
To sign up for an account, click register... Register
Hide





Powered By



Campagna Anti-IF


Skin


PARTNER
Zio Budda
HostingJava


LICENZA



Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons

Sitemap  © 2002-2004 Copyright Information. Privacy . Today is domenica 1 agosto 2010