|
Appunti informatica |
|
Visite: 2520 | Gradito: | [ Picolo appunti ] |
Leggi anche appunti:La firma digitaleLa firma digitale Un utilizzo molto diffuso della crittografia è per processi La sicurezza delle Java cardLa sicurezza delle Java card Le procedure di sicurezza delle Java Card sono |
Un utilizzo molto diffuso della crittografia è per processi di autenticazione, cioè per processi di convalida dell'identità di un utente o dell'integrità dei dati. Una tecnologia molto importante che implementa i meccanismi dell'autenticazione è la firma digitale.
La firma digitale è un procedimento di associazione di un individuo ad una particolare informazione. La firma digitale riproduce fedelmente quello che è il procedimento di firma, come concetto di comune utilizzo, con il pregio di essere molto più difficilmente falsificabile.
In pratica la firma digitale sfrutta quel servizio crittografico che è l'impronta digitale di un messaggio, finora espresso con il termine di digest di un messaggio. Il procedimento di firma di un certo documento è abbastanza facile; si prende il messaggio che si vuole firmare, se ne determina l'impronta tramite un algoritmo di digest, quindi si prende l'impronta e la chiave privata del firmatario e si fanno passare attraverso un algoritmo di firma. Quello che si ottiene è la firma di quel documento processata con quella particolare chiave privata. Quindi se alleghiamo ai documenti la loro firma, chi riceverà questi dati potrà determinare in maniera inequivocabile che chi ha firmato quei documenti aveva libero accesso alla chiave privata utilizzata.
In Figura 2‑ riportiamo lo schema a blocchi del processo di firma di un messaggio dal mittente al ricevente:
Figura : Processo di firma di un documento - tratto da [11]
Per quanto riguarda la convalida della firma questa viene effettuata tramite l'utilizzo della chiave pubblica associata alla chiave privata del presunto firmatario. Il procedimento, anche questa volta, è molto semplice, si firma con la chiave pubblica la firma ricevuta, ottenendo così un'impronta del messaggio, quindi si prende il documento originale e se ne calcola il digest. Se eseguendo il confronto tra le due impronte otteniamo che sono uguali, allora possiamo affermare con assoluta certezza che la firma digitale di quei documenti è stata effettuata con la chiave privata corrispondente alla chiave pubblica utilizzata.
In Figura 2‑ riportiamo uno schema a blocchi del processo di verifica della firma di un documento:
Figura : Processo di verifica della firma di un documento - tratta da [11]
L'avvenuta convalida di una firma garantisce che il possessore della chiave privata associata alla chiave pubblica utilizzata abbia firmato il documento, garantendo quindi il non ripudio del documento da parte del firmatario. Inoltre garantisce l'integrità dei dati in quanto non è possibile che qualcuno abbia modificato e poi firmato nuovamente il documento con la chiave del proprietario a meno che la chiave non sia stata compromessa. Quindi possiamo affermare che tutti servizi e le garanzie offerte dalla firma digitale dipendono strettamente dall'affidabilità della sicurezza della chiave privata del firmatario.
Prima di affrontare il problema della firma digitale in Java è nostro interesse dare alcune nozioni su come calcolare l'impronta di un messaggio.
Il meccanismo di calcolo di un digest di un messaggio è molto utilizzato in crittografia in quanto riduce notevolmente le dimensioni di un documento. Infatti due documenti che differiscono per pochissimo, hanno la caratteristica di generare due digest molto differenti. Inoltre è stato dimostrato che è praticamente impossibile da un digest risalire al messaggio originale, garantendo l'integrità dell'informazione contenuta.
Figura : Schema a blocchi del processo per il calcolo di un'impronta - tratta da [11]
In Java il calcolo del digest di un messaggio è affidata alla classe java.security.MessageDigest
Questa classe fornisce le implementazioni degli algoritmi di digest SHA-1 e MD5. Questi algoritmi prendono come ingresso dei dati di dimensione arbitraria e restituiscono un valore hash di dimensione fissa[1]. Un oggetto MessageDigest, per essere utilizzato, deve essere inizializzato; essendo anche questa una classe astratta, una sua istanza viene creata con il metodo getInstance() invece della classica chiamata al costruttore. Questo metodo ha bisogno che venga specificato l'algoritmo con cui si intende generare il digest. Eventualmente, come per moltissime chiamate nei package di JCA e JCE, è possibile specificare un provider oppure lasciare quello di default.
I dati vengono processati per il calcolo del digest con il metodo update(). Questo metodo ha bisogno dei dati da processare. Questi dati devono essere passati al metodo sottoforma di byte o array di byte.
Il metodo che esegue effettivamente il calcolo di un digest è comunque digest(). Questo metodo può essere anche invocato direttamente, senza prima invocare la chiamata a update(), nel caso in cui i dati da processare siano di piccole dimensioni. In ogni caso questo metodo restituisce l'hash sottoforma di array di byte.
Ritornando alla firma digitale, in Java, questo servizio è offerto dal package della JCA, java.security.Signature
Il nome della classe può sembrare ingannevole, infatti con il termine Signature ci si riferisce all'oggetto utilizzato per creare e verificare le firma digitali, mentre le firme vere e proprie vengono gestite come array di byte.
All'interno della classe Signature, sono disponibili sei metodi principali per la creazione di una firma e la sua verifica.
Questa classe è astratta, quindi anche per la firma un oggetto Signature sarà ottenuto invocando il metodo getInstance(). Analogamente agli omonimi metodi delle classi viste finora, anche questo metodo necessita di un nome di un algoritmo ed eventualmente anche di un provider. Il nome degli algoritmi passati a questo metodo è strutturato in maniera standard, ovvero è composto dal nome dell'algoritmo di creazione del digest, seguiti dalla costante "with", e terminati con il nome dell'algoritmo di firma. Quindi esempi tipici possono essere: MD5withRSA, SHA1withRSA oppure SHA1withDSA e MD5withDSA.
Come anche altre classi del package java.security, la classe Signature fornisce un'implementazione indipendente dagli algoritmi, cioè una chiamata ad un metodo di inizializzazione di un oggetto di questa classe, con un particolare algoritmo, ritorna un oggetto Signature
Un oggetto Signature può essere utilizzato per eseguire la firma oppure per verificarla. Una volta creato un oggetto di questo tipo, queste due operazioni si articolano in tre fasi:
Inizializzazione;
Aggiornamento;
Operazione conclusiva.
Per quanto riguarda l'operazione di inizializzazione, questa viene fatta tramite una chiave privata o una chiave pubblica, a seconda che si voglia effettuare un'operazione di firma o verifica, rispettivamente. Nel caso in cui si esegua la firma, occorre invocare il metodo initSign(). Questo metodo inizializza un oggetto Signature per eseguire la firma e necessita di una chiave privata, ed eventualmente un oggetto SecureRandom(). Se invece si esegue un'operazione di verifica occorre invocare il metodo initVerify(); questo metodo ha due implementazioni in quanto è possibile passargli sia una chiave pubblica sia un certificato come oggetto Certificate
Per quanto riguarda l'operazione di aggiornamento, questa viene fatta tramite chiamata al metodo update(). Quindi una volta inizializzato l'oggetto firma o l'oggetto verifica, bisogna passargli i dati tramite questo metodo. I dati devono essere passati come singolo byte, oppure come array di byte. Naturalmente, nel caso in cui si stia effettuando la firma, questi dati sono rappresentati dai dati da firmare, altrimenti dai dati indicanti la firma già effettuata e che occorre verificare.
Infine l'ultima operazione viene fatta eseguendo una chiamata al metodo sign(), se si sta eseguendo la firma, o verify(), se stiamo eseguendo la verifica.
Il metodo sign() viene eseguito sui dati da firmare e ritorna la firma sotto forma di byte.
Signature firma = Signature.getInstance("algoritmo_di_firma");
firma.initSign(KeyPair.getPrivate());
firma.update(dati);
Byte[] ByteFirmati = firma.sign();
Il metodo verify(), invece, viene eseguito passandogli l'array di byte indicante la firma e restituisce un booleano come notifica della verifica.
Se la verifica ha esito negativo potrebbe anche essere generata un'eccezione di tipo SignatureException
Signature firma = Signature.getInstance("algoritmo_di_firma");
firma.initVerify(KeyPair.getPublic());
firma.update(dati);
Byte[] ByteFirmati = firma.sign();
trycatch(SignatureException se)
Questo ultimo caso si verifica quando l'oggetto firma non è stato inizializzato correttamente oppure è in un formato diverso da quello atteso.
Appunti su: https:wwwappuntimaniacominformaticajavala-firma-digitale14php, |
|
Appunti internet | |
Tesine database | |
Lezioni c | |