Condividi tramite


Cenni preliminari sulla crittografia

La crittografia consente di proteggere i dati da visualizzazioni o modifiche non autorizzate e offre mezzi di comunicazione protetti da utilizzare in alternativa a canali che diversamente sarebbero non protetti. I dati possono essere crittografati, ad esempio, mediante un algoritmo di crittografia, trasmessi in uno stato crittografato e successivamente decrittografati dalla persona a cui sono destinati. Se una terza parte intercetta i dati crittografati, troverà molte difficoltà a decifrarli.

In una tipica situazione in cui viene utilizzata la crittografia, due parti, Elena e Paolo, comunicano su un canale non protetto. Essi desiderano che la loro comunicazione non venga compresa da chiunque li stia ascoltando. Inoltre, dal momento che non si trovano nello stesso posto, Elena deve avere la certezza che le informazioni ricevute da Paolo non siano state modificate da altre persone durante la trasmissione e che siano state inviate effettivamente da Paolo e non da qualcuno che finge di essere Paolo.

La crittografia viene quindi utilizzata per raggiungere i seguenti obiettivi:

  • Confidenzialità: proteggere da letture non autorizzate l'identità o i dati di un utente.

  • Integrità dei dati: proteggere i dati da possibili alterazioni.

  • Autenticazione: garantire che i dati provengano da una determinata fonte.

Per raggiungere questi obiettivi, è possibile utilizzare una combinazione di algoritmi e operazioni note come primitive di crittografia per creare uno schema di crittografia. Nella tabella che segue sono riportate le primitive di crittografia e il relativo impiego.

Primitiva di crittografia Utilizzo

Crittografia a chiave segreta (crittografia simmetrica)

I dati vengono trasformati, in modo che non possano essere letti da terze parti. Questo tipo di crittografia utilizza una chiave segreta a singola condivisione per crittografare e decrittografare i dati.

Crittografia a chiave pubblica (crittografia asimmetrica)

I dati vengono trasformati, in modo che non possano essere letti da terze parti. Questo tipo di crittografia utilizza una coppia di chiavi pubblica/privata per crittografare e decrittografare i dati.

Firma di crittografia

Consente di verificare che i dati provengano da una determinata persona attraverso la creazione di una firma digitale che sia univoca sono per quella persona. Questo processo utilizza anche le funzioni hash.

Hash di crittografia

Associa dati di qualsiasi lunghezza a una sequenza di dati a lunghezza fissa. Gli hash sono statisticamente univoci. La stessa sequenza a due byte, ma inviata in due istanti differenti, non avrà un hash sullo stesso valore.

Crittografia a chiave segreta

Negli algoritmi di crittografia a chiave segreta viene utilizzata una singola chiave segreta per crittografare e decrittografare i dati. È necessario proteggere la chiave dall'accesso di agenti non autorizzati in quanto chiunque sia in possesso della chiave può utilizzarla per decrittografare i dati. La crittografia a chiave segreta viene definita anche crittografia simmetrica in quanto la stessa chiave viene utilizzata sia per la crittografia che per la decrittografia. Gli algoritmi di crittografia a chiave segreta sono estremamente veloci rispetto a quelli a chiave pubblica e si prestano particolarmente all'esecuzione di trasformazioni di crittografia su flussi di dati di grandi dimensioni.

Generalmente gli algoritmi a chiave segreta, denominati crittografie dei blocchi, vengono utilizzati per crittografare un blocco di dati alla volta. Gli algoritmi di crittografia a blocchi, quali RC2, DES, TripleDES e Rijndael, trasformano a livello di crittografia un blocco di input di n byte in un blocco di output di byte crittografati. Per crittografare o decrittografare una sequenza di byte, è necessario procedere blocco per blocco. Poiché la dimensione di n è limitata, ovvero è possibile avere n = 8 byte per RC2, DES e TripleDES; n = 16 come valore predefinito, n = 24 oppure n = 32 byte per Rijndael, i valori superiori a n devono essere crittografati suddividendo i dati in blocchi.

Le classi di crittografia dei blocchi fornite nella libreria di classi di base si servono di un modello di concatenazione denominato CBC (cipher block chaining) che utilizza una chiave e un vettore di inizializzazione (IV, initialization vector) per eseguire le trasformazioni di crittografia sui dati. Per una determinata chiave segreta k, una semplice crittografia a blocchi in cui non è utilizzato un vettore di inizializzazione consentirà di crittografare lo stesso blocco di input non crittografato nello stesso blocco di output di testo crittografato. Se esistono blocchi doppi all'interno del flusso non crittografato, si avranno blocchi doppi all'interno del flusso di testo crittografato. Se utenti non autorizzati sono a conoscenza di qualche dettaglio della struttura di un blocco del testo non crittografato, potrà utilizzare tali informazioni per decrittografare il blocco di testo crittografato conosciuto ed eventualmente recuperare la chiave. Per risolvere questo problema, le informazioni tratte dal blocco precedente vengono inserite nel processo di crittografia del blocco successivo. In questo modo l'output di due blocchi di testo non crittografato identici sarà diverso. Dal momento che questa tecnica utilizza il blocco precedente per crittografare quello successivo, per la crittografia del primo blocco di dati viene utilizzato un vettore di inizializzazione. Attraverso questo sistema, anche se le intestazioni dei messaggi più comuni sono note a un utente non autorizzato, non possono essere utilizzate per decodificare una chiave.

Un modo per compromettere i dati crittografati con questo tipo di crittografia consiste nell'eseguire una ricerca approfondita di ogni possibile chiave. A seconda della dimensione della chiave utilizzata per eseguire la crittografia, questo tipo di ricerca richiede tempi di esecuzione estremamente lunghi anche su computer più veloci e risulta pertanto non fattibile. Dimensioni di chiavi maggiori sono più difficili da decifrare. Sebbene mediante la crittografia non sia teoricamente impossibile il recupero dei dati crittografati da parte di utenti non autorizzati, l'operazione viene resa estremamente complicata. Se sono necessari tre mesi per eseguire una ricerca approfondita per recuperare dati validi solo per alcuni giorni, il metodo della ricerca approfondita non sarà praticabile.

Lo svantaggio della crittografia a chiave segreta è che presuppone che due parti abbiano concordato l'utilizzo di una chiave e di un vettore di inizializzazione e che abbiano comunicato i propri valori. È necessario inoltre che la chiave sia mantenuta segreta agli utenti non autorizzati. A causa di questi problemi, la crittografia a chiave segreta viene spesso utilizzata in combinazione con la crittografia a chiave pubblica per comunicare in privato i valori della chiave e del vettore di inizializzazione.

Presupponendo che Elena e Paolo siano le due parti che vogliono comunicare su un canale non protetto, essi possono utilizzare la crittografia a chiave segreta nel modo riportato di seguito. Entrambi concordano di utilizzare un determinato algoritmo, ad esempio Rijndael, con una determinata chiave e vettore di inizializzazione. Elena compone un messaggio e crea un flusso di rete su cui inviare il messaggio. Quindi crittografa il testo utilizzando la chiave e il vettore di inizializzazione e lo invia tramite Internet. Non invia la chiave e il vettore di inizializzazione a Paolo. Paolo infatti riceve il testo crittografato e lo decrittografa utilizzando la chiave e il vettore di inizializzazione precedentemente concordati. Se la trasmissione viene intercettata, l'intercettatore non è in grado di recuperare il messaggio originale in quanto non conosce la chiave o il vettore di inizializzazione. In questo scenario la chiave deve rimanere segreta, ma non è necessario fare altrettanto con il vettore di inizializzazione. In uno scenario reale Elena o Paolo genera una chiave segreta e utilizza la crittografia a chiave pubblica (asimmetrica) per trasferire la chiave segreta (simmetrica) all'altra parte. Per ulteriori informazioni, vedere la sezione Crittografia a chiave pubblica più avanti in questo argomento.

In .NET Framework sono disponibili le seguenti classi che implementano gli algoritmi della crittografia a chiave segreta:

Crittografia a chiave pubblica

La crittografia a chiave pubblica utilizza una chiave privata che deve essere tenuta segreta agli utenti non autorizzati e una chiave pubblica che può essere resa pubblica a tutti. La chiave pubblica e la chiave privata sono collegate matematicamente. I dati crittografati con la chiave pubblica possono essere decrittografati solo con la chiave privata e i dati firmati con la chiave privata possono essere verificati solo con la chiave pubblica. La chiave pubblica può essere distribuita a tutti in quanto viene utilizzata per crittografare i dati da inviare a chi detiene la chiave privata. Entrambe le chiavi sono univoche per la sessione di comunicazione. Gli algoritmi di crittografia a chiave pubblica sono noti anche come algoritmi asimmetrici in quanto per crittografare e successivamente decrittografare i dati è necessario utilizzare due chiavi diverse.

Negli algoritmi di crittografia a chiave pubblica viene utilizzata una dimensione del buffer fissa mentre in quelli di crittografia a chiave segreta viene utilizzato un buffer di lunghezza variabile. Gli algoritmi a chiave pubblica non possono essere utilizzati per concatenare i dati in flussi allo stesso modo degli algoritmi a chiave segreta in quanto è possibile crittografare solo piccole quantità di dati. Pertanto le operazioni asimmetriche non utilizzano lo stesso modello di flusso delle operazioni simmetriche.

Le due parti, Elena e Paolo, possono utilizzare la crittografia a chiave pubblica nel modo riportato di seguito. Innanzitutto Elena genera una coppia di chiavi pubblica/privata. Se Paolo desidera inviare a Elena un messaggio crittografato, le chiede la chiave pubblica. Elena invia a Paolo la chiave pubblica su una rete non protetta e Paolo la utilizza per crittografare un messaggio. Se Paolo ha ricevuto la chiave di Elena su un canale non protetto, come ad esempio una rete pubblica, egli deve verificare con Elena di disporre della copia corretta della sua chiave pubblica. Paolo invia il messaggio crittografato a Elena, la quale lo decrittografa utilizzando la sua chiave privata.

Durante la trasmissione della chiave pubblica di Elena, tuttavia, una persona non autorizzata potrebbe intercettare la chiave e il messaggio crittografato da Paolo. Non è comunque in grado di decrittografare il messaggio con la chiave pubblica. Il messaggio può essere decrittografato solo con la chiave privata di Elena che non è stata trasmessa. Elena non utilizza la propria chiave privata per crittografare un messaggio di risposta a Paolo in quanto chiunque sia in possesso della chiave pubblica potrebbe decrittografare il messaggio. Se Elena desidera inviare un messaggio a Paolo, gli chiede la chiave pubblica e crittografa il suo messaggio utilizzando quella chiave. Paolo decrittografa il messaggio utilizzando la sua chiave privata associata.

In uno scenario reale Elena e Paolo utilizzano la crittografia a chiave pubblica (asimmetrica) per trasferire una chiave segreta (simmetrica) e utilizzano la crittografia a chiave segreta per il resto della sessione.

La crittografia a chiave pubblica ha uno spazio delle chiavi molto più grande o un intervallo di valori possibili per la chiave. Pertanto è meno esposto a tecniche esaustive per scoprire la chiave. Una chiave pubblica è facile da distribuire in quanto non deve essere protetta. Gli algoritmi a chiave pubblica possono essere utilizzati per creare firme digitali per la verifica dell'identità del mittente dei dati. Tuttavia gli algoritmi a chiave pubblica sono estremamente lenti in confronto a quelli a chiave segreta e non sono destinati alla crittografia di grandi quantità di dati. Essi risultano utili solo per il trasferimento di piccole quantità di dati. Generalmente la crittografia a chiave pubblica viene utilizzata per crittografare una chiave e un vettore di inizializzazione utilizzabili da un algoritmo a chiave segreta. Dopo il trasferimento della chiave e del vettore di inizializzazione, la crittografia a chiave segreta viene utilizzata per il resto della sessione.

In .Net Framework sono disponibili le seguenti classi che implementano gli algoritmi della crittografia a chiave pubblica:

Firme digitali

Gli algoritmi a chiave pubblica possono essere utilizzati per formare firme digitali, il cui obiettivo è l'autenticazione dell'identità di un mittente, se la chiave pubblica di quest'ultimo viene considerata attendibile, e la protezione dell'integrità dei dati. Attraverso una chiave pubblica generata da Elena, il destinatario dei suoi dati può verificare che siano stati inviati effettivamente da lei confrontando la firma digitale sui dati e la chiave pubblica di Elena.

Per apporre una firma digitale a un messaggio utilizzando la crittografia a chiave pubblica, Elena applica dapprima un algoritmo hash al messaggio per creare un digest del messaggio. Il digest è una rappresentazione dei dati compatta e univoca. Elena quindi crittografa il digest del messaggio con la sua chiave privata per creare la sua chiave personale. Alla ricezione del messaggio e della firma, Paolo decrittografa la firma con la chiave pubblica di Elena per recuperare il digest del messaggio e genera un has mediante lo stesso algoritmo hash inviato da Elena. Se il digest del messaggio calcolato da Paolo corrisponde esattamente al digest del messaggio ricevuto da Elena, Paolo ha la certezza che il messaggio provenga dal possessore della chiave privata e che i dati non siano stati modificati. Se Paolo ha la certezza che Elena sia il possessore della chiave privata, saprà che il messaggio proviene solo da Elena.

Chiunque può verificare una firma in quanto la chiave pubblica del mittente è di pubblico dominio e generalmente viene inclusa nel formato della firma digitale. Questo metodo non mantiene la segretezza del messaggio. Perché possa essere segreto, anche il messaggio deve essere crittografato.

In .Net Framework sono disponibili le seguenti classi che implementano gli algoritmi della firma digitale:

Valori hash

Gli algoritmi hash associano valori binari di lunghezza arbitraria a piccoli valori binari di lunghezza fissa, noti come valori hash. Per valore hash si intende una rappresentazione numerica univoca ed estremamente compatta di una porzione di dati. Se si inserisce un hash in un paragrafo di testo non crittografato e si modifica anche una sola lettera del paragrafo, un hash successivo produrrà un valore diverso. È computazionalmente improbabile trovare due input distinti che inseriscono l'hash sullo stesso valore.

Le funzioni hash MAC (message authentication code) vengono generalmente utilizzate con le firme digitali per apporre la firma ai dati mentre le funzioni hash MDC (message detection code) vengono utilizzate per l'integrità dei dati.

Per garantire l'integrità dei dati, due parti (Elena e Paolo) possono utilizzare una funzione hash nel seguente modo. Se Elena scrive un messaggio per Paolo e crea un hash di quel messaggio, Paolo può quindi inserire l'hash nel messaggio in un momento successivo e confrontare il suo hash con quello originale. Se i valori hash sono identici, il messaggio non è stato alterato. Se invece i dati non sono identici, il messaggio ha subito delle alterazioni dopo essere stato scritto da Elena. Perché il sistema funzioni, Elena deve nascondere il valore hash originale a tutte le parti ad eccezione di Paolo.

In .Net Framework sono disponibili le seguenti classi che implementano gli algoritmi della firma digitale:

Generazione di numeri casuali

La generazione di numeri casuali è fondamentale per molte operazioni di crittografia. Le chiavi di crittografia, ad esempio, devono essere il più casuali possibile in modo che non sia possibile riprodurle. I generatori di numeri causali di crittografia devono generare un output che sia computazionalmente impossibile da prevedere con una migliore probabilità di *p *< .05. In altre parole, qualsiasi metodo di previsione del bit di output non deve avere una prestazione migliore della previsione casuale. Le classi in .NET Framework utilizzano i generatori di numeri causali per generare chiavi di crittografia.

La classe RNGCryptoServiceProvider è un'implementazione di un algoritmo di generazione di numeri casuali.

Vedere anche

Concetti

Modello di crittografia di .NET Framework

Altre risorse

Attività di crittografia
Servizi di crittografia