Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo offre una panoramica dei metodi e delle procedure di crittografia supportati da .NET, inclusi i manifesti ClickOnce.
Introduzione alla crittografia
Le reti pubbliche, ad esempio Internet, non forniscono un mezzo di comunicazione sicura tra entità. La comunicazione su tali reti è soggetta alla lettura o alla modifica di terze parti non autorizzate. La crittografia consente di proteggere i dati dalla visualizzazione, fornisce modi per rilevare se i dati sono stati modificati e consente di fornire un mezzo sicuro di comunicazione su canali altrimenti non sicuri. Ad esempio, i dati possono essere crittografati usando un algoritmo di crittografia, trasmessi in uno stato crittografato e successivamente decrittografati dall'entità desiderata. Se una terza parte intercetta i dati crittografati, sarà difficile decifrare.
In .NET le classi nello System.Security.Cryptography spazio dei nomi gestiscono molti dettagli della crittografia. Alcuni sono wrapper per le implementazioni del sistema operativo, mentre altri sono implementazioni puramente gestite. Non è necessario essere esperti di crittografia per usare queste classi. Quando si crea una nuova istanza di una delle classi di algoritmi di crittografia, le chiavi vengono generate automaticamente per facilitare l'uso e le proprietà predefinite sono il più sicure e sicure possibile.
Primitive crittografiche
In una situazione tipica in cui viene usata la crittografia, due parti (Alice e Bob) comunicano su un canale non sicuro. Alice e Bob vogliono assicurarsi che la loro comunicazione rimanga incomprensibile da chiunque possa ascoltare. Inoltre, poiché Alice e Bob si trovano in posizioni remote, Alice deve assicurarsi che le informazioni ricevute da Bob non siano state modificate da nessuno durante la trasmissione. Inoltre, deve assicurarsi che le informazioni provengono realmente da Bob e non da qualcuno che rappresenta Bob.
La crittografia viene usata per raggiungere gli obiettivi seguenti:
Riservatezza: per proteggere l'identità o i dati di un utente dalla lettura.
Integrità dei dati: per proteggere i dati dalla modifica.
Autenticazione: per assicurarsi che i dati provengano da una determinata parte.
Non ripudio: per impedire a una determinata parte di negare l'invio di un messaggio.
Per raggiungere questi obiettivi, è possibile usare una combinazione di algoritmi e procedure note come primitive crittografiche per creare uno schema crittografico. Nella tabella seguente sono elencate le primitive crittografiche e i relativi usi.
Primitiva crittografica | Utilizzo |
---|---|
Crittografia con chiave privata (crittografia simmetrica) | Esegue una trasformazione sui dati per impedirne la lettura da parte di terze parti. Questo tipo di crittografia usa una singola chiave privata condivisa per crittografare e decrittografare i dati. |
Crittografia a chiave pubblica (crittografia asimmetrica) | Esegue una trasformazione sui dati per impedirne la lettura da parte di terze parti. Questo tipo di crittografia usa una coppia di chiavi pubblica/privata per crittografare e decrittografare i dati. |
Firma crittografica | Consente di verificare che i dati provengano da una parte specifica creando una firma digitale univoca per tale entità. Questo processo usa anche funzioni hash. |
Hash crittografici | Mappa i dati da qualsiasi lunghezza a una sequenza di byte a lunghezza fissa. Gli hash sono statisticamente univoci; una sequenza a due byte diversa non eseguirà l'hashing dello stesso valore. |
Secret-Key crittografia
Gli algoritmi di crittografia a chiave privata usano una singola chiave privata per crittografare e decrittografare i dati. È necessario proteggere la chiave dall'accesso da parte di agenti non autorizzati, perché qualsiasi entità con la chiave può usarla per decrittografare i dati o crittografare i propri dati, sostenendo che ha avuto origine dall'utente.
La crittografia con chiave privata viene definita anche crittografia simmetrica perché la stessa chiave viene usata per la crittografia e la decrittografia. Gli algoritmi di crittografia a chiave privata sono molto veloci (rispetto agli algoritmi a chiave pubblica) e sono ideali per l'esecuzione di trasformazioni crittografiche su flussi di dati di grandi dimensioni. Gli algoritmi di crittografia asimmetrica, ad esempio RSA, sono matematicamente limitati nella quantità di dati che possono crittografare. Gli algoritmi di crittografia simmetrica in genere non presentano questi problemi.
Un tipo di algoritmo a chiave privata denominato crittografia a blocchi viene usato per crittografare un blocco di dati alla volta. Crittografie a blocchi come Data Encryption Standard (DES), TripleDES e Advanced Encryption Standard (AES) trasformano in modo crittografico un blocco di input di n byte in un blocco di output di byte crittografati. Se si vuole crittografare o decrittografare una sequenza di byte, è necessario farlo blocco per blocco. Poiché n è di dimensioni ridotte (8 byte per DES e TripleDES; 16 byte [impostazione predefinita], 24 byte o 32 byte per AES), i valori di dati maggiori di n devono essere crittografati un blocco alla volta. I valori di dati inferiori a n devono essere espansi fino a n per poter essere elaborati.
Una forma semplice di crittografia a blocchi è detta modalità Electronic Codebook (ECB). La modalità BCE non è considerata sicura, perché non usa un vettore di inizializzazione per inizializzare il primo blocco di testo non crittografato. Per una determinata chiave privata k, una semplice crittografia a blocchi che non usa un vettore di inizializzazione crittograferà lo stesso blocco di input di testo non crittografato nello stesso blocco di output di testo crittografato. Pertanto, se sono presenti blocchi duplicati nel flusso di testo non crittografato di input, saranno presenti blocchi duplicati nel flusso di testo crittografato di output. Questi blocchi di output duplicati avvisano gli utenti non autorizzati riguardo alla crittografia debole, agli algoritmi che potrebbero essere stati impiegati e alle modalità di attacco possibili. La modalità di crittografia della BCE è quindi abbastanza vulnerabile all'analisi e, infine, all'individuazione chiave.
Le classi di crittografia a blocchi fornite nella libreria di classi di base usano una modalità di concatenamento predefinita denominata concatenamento a blocchi di crittografia (CBC), anche se è possibile modificare questo valore predefinito, se necessario.
Le crittografie CBC superano i problemi associati alle crittografie BCE usando un vettore di inizializzazione (IV) per crittografare il primo blocco di testo non crittografato. Ogni blocco successivo di testo non crittografato viene sottoposto a un'operazione ORXOR
() esclusiva bit per bit con il blocco di testo crittografato precedente prima che venga crittografato. Ogni blocco di testo crittografato dipende quindi da tutti i blocchi precedenti. Quando si usa questo sistema, le intestazioni comuni dei messaggi che potrebbero essere note a un utente non autorizzato non possono essere usate per invertire l'ingegnerizzazione di una chiave.
Un modo per compromettere i dati crittografati con una crittografia CBC consiste nell'eseguire una ricerca completa di ogni possibile chiave. A seconda delle dimensioni della chiave usata per eseguire la crittografia, questo tipo di ricerca richiede molto tempo usando anche i computer più veloci ed è quindi infeasible. Le dimensioni delle chiavi maggiori sono più difficili da decifrare. Anche se la crittografia non rende teoricamente impossibile per un avversario recuperare i dati crittografati, aumenta il costo di questa operazione. Se sono necessari tre mesi per eseguire una ricerca completa per recuperare i dati significativi solo per alcuni giorni, il metodo di ricerca completo non è pratico.
Lo svantaggio della crittografia a chiave privata è che si presuppone che due parti abbiano concordato una chiave e un IV e comunicato i loro valori. L'IV non è considerato un segreto e può essere trasmesso in testo in chiaro insieme al messaggio. Tuttavia, la chiave deve essere mantenuta segreta da utenti non autorizzati. A causa di questi problemi, la crittografia della chiave privata viene spesso usata insieme alla crittografia a chiave pubblica per comunicare privatamente i valori della chiave e dell'IV.
Supponendo che Alice e Bob siano due parti che vogliono comunicare tramite un canale non sicuro, potrebbero usare la crittografia a chiave privata come indicato di seguito: Alice e Bob accettano di usare un particolare algoritmo (ad esempio AES) con una chiave e un IV specifici. Alice compone un messaggio e crea un flusso di rete (ad esempio una named pipe o un messaggio di posta elettronica di rete) su cui inviare il messaggio. Successivamente, crittografa il testo usando la chiave e l'IV e invia il messaggio crittografato e l'IV a Bob sulla Intranet. Bob riceve il testo crittografato e lo decrittografa usando l'IV e la chiave concordata in precedenza. Se la trasmissione viene intercettata, l'intercettore non può recuperare il messaggio originale, perché non conosce la chiave. In questo scenario, solo la chiave deve rimanere segreta. In uno scenario reale, Alice o Bob genera una chiave privata e usa la crittografia a chiave pubblica (asimmetrica) per trasferire la chiave privata (simmetrica) all'altra parte. Per altre informazioni sulla crittografia a chiave pubblica, vedere la sezione successiva.
.NET fornisce le classi seguenti che implementano algoritmi di crittografia a chiave privata:
HMACSHA256e HMACSHA384HMACSHA512. Si tratta tecnicamente di algoritmi a chiave privata perché rappresentano codici di autenticazione dei messaggi calcolati usando una funzione hash crittografica combinata con una chiave privata. Vedere Valori hash più avanti in questo articolo.
Public-Key crittografia
La crittografia a chiave pubblica usa una chiave privata che deve essere mantenuta segreta da utenti non autorizzati e da una chiave pubblica che può essere resa pubblica a chiunque. 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 resa disponibile a chiunque; viene usato per crittografare i dati da inviare al custode della chiave privata. Gli algoritmi di crittografia a chiave pubblica sono noti anche come algoritmi asimmetrici perché è necessaria una chiave per crittografare i dati e un'altra chiave è necessaria per decrittografare i dati. Una regola di crittografia di base impedisce il riutilizzo delle chiavi e entrambe le chiavi devono essere univoche per ogni sessione di comunicazione. Tuttavia, in pratica, le chiavi asimmetriche sono generalmente di lunga durata.
Due parti (Alice e Bob) possono usare la crittografia a chiave pubblica come indicato di seguito: In primo luogo, Alice genera una coppia di chiavi pubblica/privata. Se Bob vuole inviare a Alice un messaggio crittografato, le chiede la chiave pubblica. Alice invia a Bob la chiave pubblica su una rete non protetta e Bob usa questa chiave per crittografare un messaggio. Bob invia il messaggio crittografato ad Alice e lo decrittografa usando la chiave privata. Se Bob ha ricevuto la chiave di Alice su un canale non sicuro, ad esempio una rete pubblica, Bob è aperto a un attacco man-in-the-middle. Pertanto, Bob deve verificare con Alice che abbia una copia corretta della chiave pubblica.
Durante la trasmissione della chiave pubblica di Alice, un agente non autorizzato potrebbe intercettare la chiave. Inoltre, lo stesso agente potrebbe intercettare il messaggio crittografato da Bob. Tuttavia, l'agente non può decrittografare il messaggio con la chiave pubblica. Il messaggio può essere decrittografato solo con la chiave privata di Alice, che non è stata trasmessa. Alice non usa la chiave privata per crittografare un messaggio di risposta a Bob, perché chiunque abbia la chiave pubblica potrebbe decrittografare il messaggio. Se Alice vuole inviare un messaggio a Bob, chiede a Bob la chiave pubblica e crittografa il messaggio usando tale chiave pubblica. Bob decrittografa quindi il messaggio usando la chiave privata associata.
In questo scenario Alice e Bob usano la crittografia a chiave pubblica (asimmetrica) per trasferire una chiave privata (simmetrica) e usare la crittografia della chiave privata per il resto della sessione.
L'elenco seguente offre confronti tra algoritmi di crittografia a chiave pubblica e a chiave privata:
Gli algoritmi di crittografia a chiave pubblica usano una dimensione fissa del buffer, mentre gli algoritmi di crittografia a chiave privata usano un buffer a lunghezza variabile.
Gli algoritmi a chiave pubblica non possono essere usati per concatenare i dati in flussi nel modo in cui gli algoritmi a chiave privata possono essere crittografati perché è possibile crittografare solo piccole quantità di dati. Pertanto, le operazioni asimmetriche non usano lo stesso modello di streaming delle operazioni simmetriche.
La crittografia a chiave pubblica ha uno spazio chiavi molto più ampio (intervallo di valori possibili per la chiave) rispetto alla crittografia della chiave privata. Pertanto, la crittografia a chiave pubblica è meno soggetta a attacchi completi che tentano ogni possibile chiave.
Le chiavi pubbliche sono facili da distribuire perché non devono essere protette, purché esista un modo per verificare l'identità del mittente.
Alcuni algoritmi a chiave pubblica( ad esempio RSA e DSA, ma non Diffie-Hellman) possono essere usati per creare firme digitali per verificare l'identità del mittente dei dati.
Gli algoritmi a chiave pubblica sono molto lenti rispetto agli algoritmi di chiave privata e non sono progettati per crittografare grandi quantità di dati. Gli algoritmi a chiave pubblica sono utili solo per il trasferimento di quantità di dati molto piccole. In genere, la crittografia a chiave pubblica viene utilizzata per crittografare una chiave e un vettore di inizializzazione da usare con un algoritmo a chiave segreta. Dopo il trasferimento della chiave e dell'iv, viene usata la crittografia della chiave privata per il resto della sessione.
.NET fornisce le classi seguenti che implementano algoritmi a chiave pubblica:
RSA consente sia la crittografia che la firma, ma DSA può essere usata solo per la firma. DSA non è sicuro come RSA e si consiglia RSA. Diffie-Hellman può essere usato solo per la generazione di chiavi. In generale, gli algoritmi a chiave pubblica sono più limitati negli usi rispetto agli algoritmi a chiave privata.
Firme digitali
Gli algoritmi a chiave pubblica possono essere usati anche per formare firme digitali. Le firme digitali autenticano l'identità di un mittente (se si considera attendibile la chiave pubblica del mittente) e consentono di proteggere l'integrità dei dati. Usando una chiave pubblica generata da Alice, il destinatario dei dati di Alice può verificare che Alice l'abbia inviata confrontando la firma digitale con i dati di Alice e la chiave pubblica di Alice.
Per usare la crittografia a chiave pubblica per firmare digitalmente un messaggio, Alice applica innanzitutto un algoritmo hash al messaggio per creare un digest del messaggio. Il digest del messaggio è una rappresentazione compatta e univoca dei dati. Alice crittografa quindi il digest del messaggio con la chiave privata per creare la firma personale. Dopo aver ricevuto il messaggio e la firma, Bob decrittografa la firma usando la chiave pubblica di Alice per recuperare il digest del messaggio e esegue l'hashing del messaggio usando lo stesso algoritmo hash usato da Alice. Se il digest del messaggio che Bob calcola esattamente corrisponde al digest del messaggio ricevuto da Alice, Bob garantisce che il messaggio provenisse dal possessore della chiave privata e che i dati non siano stati modificati. Se Bob ritiene che Alice sia il proprietario della chiave privata, sa che il messaggio proviene da Alice.
Annotazioni
Una firma può essere verificata da chiunque perché la chiave pubblica del mittente è di conoscenza comune ed è in genere inclusa nel formato di firma digitale. Questo metodo non mantiene la segretezza del messaggio; affinché il messaggio sia segreto, deve anche essere crittografato.
.NET fornisce le classi seguenti che implementano algoritmi di firma digitale:
Valori hash
Gli algoritmi hash eseguono il mapping dei valori binari di una lunghezza arbitraria a valori binari più piccoli di lunghezza fissa, noti come valori hash. Un valore hash è una rappresentazione numerica di una parte di dati. Se si esegue l'hashing di un paragrafo di testo non crittografato e si modifica anche una lettera del paragrafo, un hash successivo produrrà un valore diverso. Se l'hash è crittograficamente sicuro, il valore cambierà significativamente. Ad esempio, se viene modificato un singolo bit di un messaggio, una funzione hash forte può produrre un output che differisce del 50%. Molti valori di input possono essere convertiti nello stesso valore di output. Tuttavia, è non fattibile in modo computazionale trovare due input distinti che producano lo stesso valore di hash.
Due parti (Alice e Bob) possono usare una funzione hash per garantire l'integrità dei messaggi. Selezionare un algoritmo hash per firmare i messaggi. Alice scrive un messaggio e quindi crea un hash di tale messaggio usando l'algoritmo selezionato. Seguono quindi uno dei metodi seguenti:
Alice invia il messaggio di testo non crittografato e il messaggio con hash (firma digitale) a Bob. Bob riceve e genera un hash del messaggio e confronta il suo valore hash con quello che ha ricevuto da Alice. Se i valori hash sono identici, il messaggio non è stato modificato. Se i valori non sono identici, il messaggio è stato modificato dopo che Alice lo ha scritto.
Sfortunatamente, questo metodo non stabilisce l'autenticità del mittente. Chiunque può rappresentare Alice e inviare un messaggio a Bob. Possono usare lo stesso algoritmo hash per firmare il loro messaggio, e tutto quello che Bob può determinare è che il messaggio corrisponde alla sua firma. Si tratta di una forma di attacco man-in-the-middle. Per altre informazioni, vedere Esempio di comunicazione sicura CNG (Cryptography Next Generation).
Alice invia il messaggio di testo non crittografato a Bob su un canale pubblico non sicuro. Invia il messaggio con hash a Bob su un canale privato sicuro. Bob riceve il messaggio di testo non crittografato, lo hash e confronta l'hash con l'hash scambiato privatamente. Se gli hash corrispondono, Bob conoscerà due cose:
Il messaggio non è stato modificato.
Il mittente del messaggio (Alice) è autentico.
Per consentire il funzionamento di questo sistema, Alice deve nascondere il valore hash originale a tutte le parti eccetto Bob.
Alice invia il messaggio di testo non crittografato a Bob su un canale pubblico non sicuro e inserisce il messaggio con hash nel suo sito Web visualizzabile pubblicamente.
Questo metodo impedisce la manomissione dei messaggi impedendo a chiunque di modificare il valore hash. Anche se il messaggio e il relativo hash possono essere letti da chiunque, il valore hash può essere modificato solo da Alice. Un utente malintenzionato che vuole fingersi Alice avrebbe bisogno di accedere al sito Web di Alice.
Nessuno dei metodi precedenti impedirà a un utente di leggere i messaggi di Alice, perché vengono trasmessi in testo non crittografato. La sicurezza completa richiede in genere firme digitali (firma dei messaggi) e crittografia.
.NET fornisce le classi seguenti che implementano algoritmi hash:
.NET fornisce anche MD5 e SHA1. Tuttavia, gli algoritmi MD5 e SHA-1 sono stati trovati non sicuri e SHA-2 è ora consigliato. SHA-2 include SHA256, SHA384 e SHA512.
Generazione di numeri casuali
La generazione di numeri casuali è integrale a molte operazioni di crittografia. Ad esempio, le chiavi crittografiche devono essere il più casuali possibile in modo che sia infeasibile riprodurle. I generatori di numeri casuali crittografici devono produrre un output che sia impossibile da prevedere dal punto di vista computazionale con una probabilità migliore di un mezzo. Pertanto, qualsiasi metodo di stima del bit di output successivo non deve offrire prestazioni migliori rispetto all'ipotesi casuale. Le classi in .NET usano generatori di numeri casuali per generare chiavi crittografiche.
La RandomNumberGenerator classe è un'implementazione di un algoritmo generatore di numeri casuali.
Manifesti di ClickOnce
Le classi di crittografia seguenti consentono di ottenere e verificare informazioni sulle firme manifesto per le applicazioni distribuite tramite la tecnologia ClickOnce:
La ManifestSignatureInformation classe ottiene informazioni su una firma del manifesto utilizzando gli overload dei VerifySignature metodi.
È possibile usare l'enumerazione ManifestKinds per specificare i manifesti da verificare. Il risultato della verifica è uno dei SignatureVerificationResult valori di enumerazione.
La ManifestSignatureInformationCollection classe fornisce una raccolta di sola lettura di ManifestSignatureInformation oggetti delle firme verificate.
Inoltre, le classi seguenti forniscono informazioni specifiche sulla firma:
StrongNameSignatureInformation contiene le informazioni sulla firma con nome forte per un manifesto.
AuthenticodeSignatureInformation rappresenta le informazioni sulla firma Authenticode per un manifesto.
TimestampInformation contiene informazioni sul timestamp di una firma Authenticode.
TrustStatus fornisce un modo semplice per verificare se una firma Authenticode è attendibile.
Classi di crittografia di nuova generazione (CNG)
Le classi Cryptography Next Generation (CNG) forniscono un wrapper gestito per le funzioni CNG native. CNG è la sostituzione di CryptoAPI. Queste classi hanno "Cng" come parte dei nomi. Al centro delle classi wrapper CNG c'è la classe contenitore chiave, che astrae l'archiviazione e l'uso delle chiavi CNG. Questa classe consente di archiviare in modo sicuro una coppia di chiavi o una chiave pubblica e farvi riferimento usando un nome stringa semplice. La classe di firma basata sulla ECDsaCng curva ellittica e la classe di ECDiffieHellmanCng crittografia possono usare CngKey oggetti .
La CngKey classe viene usata per un'ampia gamma di operazioni aggiuntive, tra cui apertura, creazione, eliminazione ed esportazione delle chiavi. Fornisce anche l'accesso all'handle di chiave sottostante da usare quando si chiamano direttamente le funzioni native.
.NET include anche un'ampia gamma di classi CNG di supporto, ad esempio le seguenti:
CngProvider gestisce un provider di archiviazione delle chiavi.
CngAlgorithm mantiene un algoritmo CNG.
CngProperty mantiene le proprietà chiave frequentemente utilizzate.
Vedere anche
- Modello di crittografia: descrive come viene implementata la crittografia nella libreria di classi di base.
- Crittografia multipiattaforma
- Vulnerabilità temporali con la decrittografia simmetrica in modalità CBC tramite riempimento
- ASP.NET protezione dei dati di base