Il jarsigner è utilizzato per assolvere due compiti fondamentali nell'ambito della sicurezza di archivi Java: firmare un file JAR e verificare firma e integrità del file stesso.
Una firma digitale è semplicemente una stringa di bit ottenuta da una file utilizzando un particolare algoritmo e una chiave privata. Una firma digitale ha le caratteristiche che andiamo ad elencare:
- consente la verifica della sua autenticità utilizzando la chiave pubblica corrispondente alla chiave privata utilizzata per la sua generazione;
- non può essere falsificata né manipolata in quanto la chiave privata è custodita dal solo proprietario;
- risulta essere una funzione dei dati firmati e non può quindi essere rivendicata come firma di altri dati.
Generare una firma digitale
Per generare una firma digitale appartenente a un'entità, ad esempio una società di nome Microsystem Inc, è necessario che l'entità stessa sia in possesso di una chiave pubblica e di una chiave
privata. Inoltre il certificato con la chiave pubblica dovrebbe essere firmato da un'autorità di certificazione garante della sua autenticità. Il comando jarsigner
utilizza la chiave privata presente nel keystore per generare una signature del file.
Tale comando non agisce direttamente sul file ma crea a partire da esso un nuovo file JAR (versione con firma digitale) contenente, all'interno del percorso META-INF
, un file con estensione SF e uno con estensione RSA, DSA o EC. Vediamo un esempio di generazione di una firma digitale nella sua forma più semplice:
jarsigner -keystore keystore.jks -signedjar signed_document.jar document.jar "Microsystems Inc"
Il file signed_document.jar
è il file firmato digitalmente ottenuto dal file document.jar
utilizzando la chiave privata e il certificato a chiave pubblica presenti nel keystore specificato. "Microystem Inc", alias del keystore, è l'entità per la quale la firma è generata.
Signature e Signature block
L'output del comando jarsigner
è esattamente il file di input al quale vengono aggiunti un Signature File (estensione .SF) e un Signature Block File ( estensioni .DSA,.RSA,.EC). Per ciascun file sorgente contenuto nel file sorgente, il file .SF ha tre contenuti informativi: il nome del file, nome dell'algoritmo di digest (SHA) utilizzato, e il digest value SHA.
Il digest value è un valore hash calcolato sui dati binari del file sorgente. Il file .SF è firmato a sua volta e la sua firma viene collocata nel Signature Block File. Il Signature Block File contiene inoltre il certificato a chiave pubblica dell'entità firmataria e la catena di certificati necessaria per la verifica del certificato stesso.
L'estensione del file varia in funzione dell'algoritmo utilizzato e della dimensione della chiave privata: DSA (SHA256withDSA) chiave di qualsiasi lunghezza, RSA (SHA256withDSA, SHA384withDSA, SHA512withDSA) lunghezza chiave minore o uguale a 3072, minore o uguale 7680 o maggiore di 7680 rispettivamente, EC (SHA256withDSA, SHA384withDSA, SHA512withDSA) con lunghezza chiave minore 384, minore di 512 o uguale a 512.
Verifica di un file firmato
La verifica con successo di un file JAR firmato avviene quando le signatures presenti nel file sono valide e nessuno dei file contenuti nel JAR ha subito modifiche dal momento della generazione della firma. La verifica del file si articola nei seguentistep:
- verifica della firma del file .SF utilizzando il Signature Block File;
- verifica dei valori di digest per ciascuna entry listata nel file .SF;
- lettura dei file del JAR listati nel file .SF. Per ciascun file viene calcolato il digest e comparato con il valore di digest di riferimento generato durante la firma.
Vediamo un esempio. Per verificare il file ottenuto dalla Micorsystem Inc, andiamo ad utilizzare il jarsigner con le seguenti opzioni:
jarsigner -verify -verbose -certs signed_document.jar
Otterremo una stampa dettagliata del processo che si conclude con un messaggio jar verified
se la verifica si è conclusa con successo.