A volte ritornano... CAPICOM - parte 2 - Firma Digitale

Partendo dall'overview della prima parte, in questa seconda parte affrontiamo il tema dell'architettura di riferimento per CAPICOM e le operazioni di firma!

Architettura su cui si basa CAPICOM

CAPICOM lavora con il paradigma dell’ architettura del sistema di crittografia di Windows XP/2003 il quale comprende tre elementi fondamentali : l’ applicazione, il sistema operativo e i Cryptographic Service Provider (CSP). Le applicazioni comunicano con il sistema operativo tramite le CryptoAPI e il sistema operativo a sua volta comunica con i CSP tramite i Cryptographic Service Provider Interface (CSPI). I CSP sono dei moduli indipendenti che eseguono tutte le operazioni di crittografia, come la generazione di chiavi di sessione (chiavi simmetriche), chiavi asimmetriche (pubblica/privata) e operazioni di firma. Alcuni CSP implementano le loro funzioni via software come ad esempio i tre CSP forniti da Microsoft: Base CSP, Enhanced CSP e Strong CSP, mentre altri le implementano tramite dispositivi hardware esterni come le smart-cards mantenendo però inalterata l’interfaccia di programmazione per il client.

Generalmente i dispositivi hardware vengono utilizzati quando il fattore sicurezza è determinante, come nelle applicazioni che integrano la firma digitale conforme alla Legge (firma di sottoscrizione prevista dal DPR 445/2000, firme digitali utilizzate per “archiviazione ottica sostitutiva” – deliberazione AIPA 24/98), oppure come il logon ad un sistema operativo. Per ragioni di sicurezza e di portabilità le applicazioni che richiedono i servizi di crittografia tramite i CSP possono scegliere varie opzioni come il tipo di algoritmo da usare per la firma elettronica o per l’ encryption e la lunghezza delle chiavi. Tuttavia non è possibile interagire direttamente con i dati interni del CSP, infatti per accedere alle chiavi di crittografia le applicazioni utilizzano come riferimenti degli “opaque handle”.

Ciò che distingue un CSP da un altro è il grado di sicurezza che implementa al suo interno, dato dalla lunghezza delle chiavi che è in grado di gestire e dagli algoritmi implementati.
Fisicamente i CSP sono composti almeno da un file con estensione .DLL che consente le operazioni di crittografia, e da una firma elettronica che Windows utilizza per verificare l’integrità del sistema.

Se il CSP è stato sviluppato per ambienti misti (Windows 98, Windows NT e Windows 2000) la firma utilizzata per garantire l’integrità del CSP risiede nel registry, mentre se il CSP è stato scritto per sistemi operativi Windows 2003/XP la firma può essere una risorsa dello stesso file .DLL. In questo caso si evidenzia che la risorsa deve avere una dimensione fissa di 144 bytes e deve essere identificata dal numero 0x29A, rendendo così meno probabile un disallineamento in fase di installazione o aggiornamento.

Esistono vari esempi di utilizzo dei CSP e delle CryptoAPI da parte del sistema operativo: l’EFS (Encryption File System) di Windows XP/2003, ad esempio, si basa sulle CryptoAPI per la generazione delle chiavi simmetriche e per le operazioni di cifratura; Authenticode, servizio che verifica la provenienza e l’integrità dei componenti scaricati tramite Internet/Intranet, gestisce la verifica della firma dei componenti per mezzo delle CryptoAPI e quindi i CSP. Anche i programmatori hanno a disposizione componenti “out of the box” che fanno largo utilizzo dei CSP, come WININET.DLL, libreria ad alto livello per l’utilizzo - lato client - dei protocolli Internet come HTTP, FTP, Gopher e HTTPS .

Ogni CSP ha un database delle chiavi chiamato “Key database” il quale contiene uno o più “Key containers” all’interno dei quali vengono effettivamente registrate le coppie di chiavi pubblica/privata di tipo signature ed exchange. Le prime sono utilizzate per operazioni di firma elettronica, le altre per cifrare le chiavi di sessione.

image

Questi key containers hanno un nome univoco che permette ai client di connettersi tramite CryptAquireContext, un’ API appartenente alla famiglia delle CryptoAPI.

L’ActiveX CAPICOM, essendo un wrapper delle CryptoAPI, si interpone tra le applicazioni e le CryptoAPI.

CAPICOM sfrutta la dual interface, ovvero combina i metodi IDispatch e custom all’interno della stessa vTable, permettendo ai client Automation l’uso di una sola parte della vTable. In questo modo viene estesa la possibilità di utilizzo delle funzioni di crittografia ad un ampio ventaglio di ambienti di programmazione anche ad alto livello.

Firma Digitale con CAPICOM

L’introduzione del concetto di firma nell’ambito informatico ha permesso di erogare vari servizi per il controllo di integrità e di non ripudiabilità di documenti (intendendo per documenti una qualsiasi rappresentazione binaria). Alla base della firma elettronica vi è l’utilizzo delle chiavi asimmetriche, ovvero di una coppia di chiavi (numeri) utilizzate una per firmare e l’altra per verificare la firma. Caratteristica delle chiavi di firma asimmetriche è l’improbabilità di ricavare una delle chiavi partendo dall’altra. Delle due chiavi, quella utilizzata per firmare è definita “privata”, mentre quella usata per la verifica della firma è definita “pubblica”. La chiave privata deve essere mantenuta segreta, mentre quella pubblica deve essere consultabile da terze parti.

Nelle applicazioni PKI (Public Key Infrastructure) vengono normalmente utilizzati due signature scheme diversi: DSA (Digital Signature Algorithm) e RSA (Rivest, Shamir, Adleman). Il DSA basa la propria sicurezza sfruttando il problema del logaritmo discreto mentre RSA basa la propria sicurezza utilizzando particolari proprietà formali dei numeri primi molto grandi (valori da 1000 bits o più in cui ogni bit è significativo). Nel 1994 DSA fu scelto dal NIST (National Institute of Standards and Technology) e dalla NSA (National Security Agency) come standard per la firma digitale del governo USA. Fin dagli inizi fu sollevata la questione riguardante la velocità di esecuzione durante la verifica delle firme poiché, pur essendo la generazione della firma elettronica più veloce rispetto a quella di RSA, le operazioni di verifica sono decisamente più lente. Tali obiezioni furono sollevate in quanto in applicazioni PKI sono maggiori le operazioni di verifica rispetto a quelle di firma. Inoltre DSA può essere utilizzato solamente per calcolare le digital signature e non per l’encryption a chiavi asimmetriche. Viceversa RSA è più veloce nelle operazioni di verifica e può essere utilizzato per l’encryption a chiavi asimmetriche. Questa versatilità ha imposto RSA come maggiore standard mondiale nelle applicazioni PKI.

CAPICOM è in grado di lavorare con chiavi di tipo RSA e DSA. L’unico vincolo è che il CSP utilizzato le supporti.

Un altro “attore” presente nelle operazioni di firma e di verifica è l’Hash o impronta. Un Hash è il risultato di una funzione che riceve in input una sequenza di simboli binari a dimensione variabile e produce in output un’altra sequenza di simboli binari di dimensioni fisse. Un Hash quindi rappresenta in forma compatta un qualsiasi insieme di bit. Le caratteristiche principali di queste funzioni sono la facilità di calcolo e la compressione. Esistono due grandi famiglie di Hash: Keyed (con chiavi) e Unkeyed (senza chiavi). In questo contesto parleremo espressamente di Hash unkeyed e in particolare della sottoclasse MDC (Modification detection codes)

 

image 

Gli Hash MDC, chiamati anche manipulation detection codes, hanno principalmente lo scopo di garantire l’integrità dei dati focalizzandosi maggiormente su due proprietà: one way hash functions (OWHFs) e collision resistant hash functions (CRHFs) o collision free. Con la proprietà OWHF viene assicurata una notevole difficoltà computazionale nel calcolare i bit di input partendo da quelli di output (l’hash), mentre la proprietà CRHF assicura una bassissima percentuale di probabilità di calcolare due impronte uguali partendo da input diversi.

Sebbene le CryptoAPI supportano molti algoritmi di Hash, CAPICOM per le operazioni di firma utilizza lo SHA-1 e non esiste nessuna interfaccia che permetta di cambiare tale algoritmo.

Per completare il quadro, avendo a disposizione la coppia di chiavi e le funzioni di Hash, manca un’entità che associ la persona (l’utente, la macchina o un servizio) alle chiavi: il certificato.

Il certificato è un documento rilasciato da un terza parte di fiducia la quale si assume l’onere di verificare le credenziali del richiedente e dare una validità temporale alle chiavi.

In crittografia le operazione di firma e di verifica si dividono in diverse fasi: la firma elettronica si genera partendo da un hash del documento in chiaro e successivamente si cifra l’hash con la propria chiave privata. La verifica, un’operazione leggermente più complessa, avviene tramite il certificato del firmatario dal quale si estrae la chiave pubblica utilizzata per decifrare l’hash generato durante la fase di firma. Una volta ottenuto l’hash in chiaro si rigenera indipendentemente l’hash del documento da verificare e se entrambe le impronte sono uguali, la firma è valida. In questa fase è possibile controllare la validità del certificato appartenente al soggetto firmatario verificando che il certificato non sia scaduto, sospeso o revocato dalla CA (tramite la pubblicazione in una CRL).

Uno dei primari obiettivi perseguiti durante lo sviluppo di CAPICOM è stato quello di rendere il più semplice possibile alcune operazioni crittografiche. Per apporre una firma digitale, tralasciando i necessari controlli sugli errori, sarebbero sufficienti solamente tre righe:

…………………

Dim firma As New SignedData

firma.Content = bufferToSign

msgbox firma.Sign

………………….

Questo esempio crea un’istanza dell’oggetto SignedData, gli associa il buffer da firmare ed infine visualizza in una messagebox il risultato dell’operazione di firma codificato. Non avendo selezionato programmaticamente nessun certificato CAPICOM in automatico visualizza una DialogBox contenente la lista dei certificati installati sulla macchina.

Figura5

Il metodo Sign richiede tre parametri : Signer as Signer, bDetached as Boolean e EncodingType as CAPICOM_ENCODING_TYPE. L’oggetto Signer ( primo parametro) rappresenta il firmatario che deve avere accesso alla chiave privata relativa al certificato utilizzato. Sul platform SDK, nella sessione remarks, è possibile trovare una serie di casistiche sul funzionamento del metodo per Signer uguale o diverso da NULL, in concomitanza con il numero di certificati nello store e in relazione alla proprietà booleana Settings.EnablePromptForCertificateUI (per le applicazioni middle-tier impostare sempre Settings.EnablePromptForCertificateUI a FALSE).

Il secondo parametro bDetached impostato a TRUE indica che l’hash firmato viene salvato in un file separato rendendo necessario disporre di entrambi i files per l’operazione di verifica. Quando bDetached è FALSE viene creato un unico file contenente il documento in chiaro e la firma. In entrambi i casi i files contenenti le firme vengono salvati nel formato standard PKCS#7 rendendo possibile l’eventuale operazione di verifica anche tramite altre applicazioni PKI.

image

volendo "esplodere" il formato PKCS#7 otteniamo:

image

L’ultimo parametro EncodingType rappresenta il tipo di codifica utilizzata per il buffer contenente la firma. I valori ammessi sono CAPICOM_ENCODE_BASE64 dove i dati vengono salvati in una stringa base64 e CAPICOM_ENCODE_BINARY in cui vengono salvati in formato binario.

Sempre tramite l’interfaccia ISignedData è possibile firmare ripetutamente un documento tramite il metodo Cosign. La firma di più persone su un contratto oppure l’approvazione di documenti all’interno di un processo di workflow sono esempi di utilizzo di tale metodo. Come in Sign, anche in Cosign valgono le stesse regole sulla presenza di un certificato valido con la propria chiave privata.

L’operazione di verifica avviene anch’essa tramite un metodo esposto da SignedData: SignedData.Verify (SignedMessage as String, bDetached as boolean, VerifyFlag as CAPICOM_SIGNED_DATA_VERIFY_FLAG) . Semplicemente richiamando tale metodo vengono effettuati tutti i passi necessari per la verifica della o delle firme associate al documento. I primi due parametri sono equivalenti a quelli presenti in SignedData.Sign mentre l’ultimo indica la politica di controllo. Il tipo dato CAPICOM_SIGNED_DATA_VERIFY_FLAGpuò assumere due valori: CAPICOM_VERIFY_SIGNATURE_ONLY per controllare solamente la validità della firma, CAPICOM_VERIFY_SIGNATURE_AND_CERTIFICATE aggiunge il controllo completo sulla validità del certificato.

Un Sempio in HTML

Anche una semplice pagina HTML può fungere da container per CAPICOM permettendo all' utente di inserire le proprie informazioni e firmarle digitalmente.
Questo esempio lo trovate all'interno del CAB di installazione di CAPICOM.

1) una banalissima form

image

2) Selezionate il certificato. Dovete avere almeno 1 certificato nel personal store dei certificati, ovvero almeno un certificato con la chiave privata associata.

image

3) e premete FIRMA. Quello che si vede è il famoso pacchetto PKCS#7 encodato in BASE64

image

4) Premendo verifica si ottiene il controllo del pacchetto pkcs#7.

image

Un Sempio .NET/CAPICOM

Un esempio più significiativo che trovate semre nell' SDK è questo progetto .NET che utilizza CAPICOM per creare la struttura di XMLDSIG (EXML DIgital Signature). Il .NET framework è in grado fin dalle prime versioni di gestire la specifica XMLDSIG ma in questo caso si può vedere l'utilizzo congiunto .NET/CAPICOM

image

image

Nel prossimo post parlerò delle varie forme di encryption supportate da CAPICOM e alcuni tips & tricks

--Mario