Crittografia dei dati
La crittografia simmetrica e quella asimmetrica vengono eseguite utilizzando processi differenti. La crittografia simmetrica viene eseguita su flussi e risulta pertanto utile per decrittografare grandi quantità di dati. La crittografia asimmetrica viene eseguita su un numero limitato di byte e risulta pertanto utile solo per piccole quantità di dati.
Crittografia simmetrica
Le classi di crittografia simmetrica gestite vengono utilizzate con una classe di flussi speciale denominata CryptoStream che esegue la crittografia dei dati letti nel flusso. La classe CryptoStream viene inizializzata con una classe di flussi gestita, una classe che implementa l'interfaccia ICryptoTransform, creata da una classe che implementa un algoritmo di crittografia, e un'enumerazione CryptoStreamMode che descrive il tipo di accesso consentito a CryptoStream. La classe CryptoStream può essere inizializzata utilizzando qualsiasi classe derivata dalla classe Stream, incluse FileStream, MemoryStream e NetworkStream. Utilizzando queste classi è possibile eseguire una crittografia simmetrica su diversi oggetti flusso.
Nell'esempio riportato di seguito viene illustrato come creare una nuova istanza della classe RijndaelManaged che implementa l'algoritmo di crittografia Rijndael e come utilizzarla per eseguire la crittografia su una classe CryptoStream. Nell'esempio la classe CryptoStream viene inizializzata con un oggetto flusso denominato MyStream che può essere qualsiasi tipo di flusso gestito. La chiave e il vettore di inizializzazione utilizzati per la crittografia vengono passati al metodo CreateEncryptor della classe RijndaelManaged. In questo caso vengono utilizzati la chiave e il vettore di inizializzazione predefiniti generati da RMCrypto. Infine viene passato CryptoStreamMode.Write, specificando l'accesso in scrittura al flusso.
Dim RMCrypto As New RijndaelManaged()
Dim CryptStream As New CryptoStream(MyStream, RMCrypto.CreateEncryptor(RMCrypto.Key, RMCrypto.IV), CryptoStreamMode.Write)
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream CryptStream = new CryptoStream(MyStream, RMCrypto.CreateEncryptor(), CryptoStreamMode.Write);
Dopo l'esecuzione del codice precedente, qualsiasi dato scritto nell'oggetto CryptoStream viene crittografato utilizzando l'algoritmo Rijndael.
Nell'esempio che segue viene illustrato l'intero processo di creazione di un flusso, di crittografia del flusso, di scrittura nel flusso e di chiusura del flusso. In questo esempio viene creato un flusso di rete crittografato utilizzando la classe CryptoStream e la classe RijndaelManaged. Un messaggio viene scritto nel flusso crittografato con la classe StreamWriter.
Nota |
---|
È possibile utilizzare questo esempio anche per scrivere in un file.A tale scopo, eliminare il riferimento TcpClient e sostituire NetworkStream con FileStream. |
Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Net.Sockets
Module Module1
Sub Main()
Try
'Create a TCP connection to a listening TCP process.
'Use "localhost" to specify the current computer or
'replace "localhost" with the IP address of the
'listening process.
Dim TCP As New TcpClient("localhost", 11000)
'Create a network stream from the TCP connection.
Dim NetStream As NetworkStream = TCP.GetStream()
'Create a new instance of the RijndaelManaged class
'and encrypt the stream.
Dim RMCrypto As New RijndaelManaged()
Dim Key As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}
Dim IV As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}
'Create a CryptoStream, pass it the NetworkStream, and encrypt
'it with the Rijndael class.
Dim CryptStream As New CryptoStream(NetStream, RMCrypto.CreateEncryptor(Key, IV), CryptoStreamMode.Write)
'Create a StreamWriter for easy writing to the
'network stream.
Dim SWriter As New StreamWriter(CryptStream)
'Write to the stream.
SWriter.WriteLine("Hello World!")
'Inform the user that the message was written
'to the stream.
Console.WriteLine("The message was sent.")
'Close all the connections.
SWriter.Close()
CryptStream.Close()
NetStream.Close()
TCP.Close()
Catch
'Inform the user that an exception was raised.
Console.WriteLine("The connection failed.")
End Try
End Sub
End Module
using System;
using System.IO;
using System.Security.Cryptography;
using System.Net.Sockets;
public class main
{
public static void Main(string[] args)
{
try
{
//Create a TCP connection to a listening TCP process.
//Use "localhost" to specify the current computer or
//replace "localhost" with the IP address of the
//listening process.
TcpClient TCP = new TcpClient("localhost",11000);
//Create a network stream from the TCP connection.
NetworkStream NetStream = TCP.GetStream();
//Create a new instance of the RijndaelManaged class
// and encrypt the stream.
RijndaelManaged RMCrypto = new RijndaelManaged();
byte[] Key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
//Create a CryptoStream, pass it the NetworkStream, and encrypt
//it with the Rijndael class.
CryptoStream CryptStream = new CryptoStream(NetStream,
RMCrypto.CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
//Create a StreamWriter for easy writing to the
//network stream.
StreamWriter SWriter = new StreamWriter(CryptStream);
//Write to the stream.
SWriter.WriteLine("Hello World!");
//Inform the user that the message was written
//to the stream.
Console.WriteLine("The message was sent.");
//Close all the connections.
SWriter.Close();
CryptStream.Close();
NetStream.Close();
TCP.Close();
}
catch
{
//Inform the user that an exception was raised.
Console.WriteLine("The connection failed.");
}
}
}
Perché l'esempio precedente possa essere eseguito correttamente, è necessario che esista un processo in ascolto sull'indirizzo IP e sul numero di porta specificato nella classe TCPCLient. Se esiste un processo in ascolto, il codice si connetterà a tale processo, crittograferà il flusso utilizzando l'algoritmo simmetrico Rijndael e scriverà "Hello World!" nel flusso. Se il codice viene eseguito correttamente, nella console verrà visualizzato il seguente testo:
The message was sent.
Se tuttavia non viene trovato alcun processo in ascolto o viene generata un'eccezione, il codice visualizzerà quanto segue alla console:
The connection failed.
Crittografia asimmetrica
Gli algoritmi asimmetrici vengono generalmente utilizzati per crittografare piccole quantità di dati quali la crittografia di una chiave e di un vettore di inizializzazione simmetrici. Di solito un utente che esegue la crittografia asimmetrica utilizza la chiave pubblica generata da un'altra parte. La classe RSACryptoServiceProvider viene fornita da .NET Framework a questo scopo.
Nell'esempio che segue vengono utilizzate le informazioni sulla chiave pubblica per la crittografia di una chiave e un vettore di inizializzazione simmetrici. Vengono inizializzate due matrici di byte che rappresentano la chiave pubblica di una terza parte. Un oggetto RSAParameters viene inizializzato in base a questi valori. Successivamente, l'oggetto RSAParameters viene importato insieme alla chiave pubblica che rappresenta in un oggetto RSACryptoServiceProvider mediante il metodo RSACryptoServiceProvider.ImportParameters. Infine vengono crittografati la chiave privata e il vettore di inizializzazione creati da una classe RijndaelManaged. Questo esempio presuppone che nei sistemi sia installata una crittografia a 128 bit.
Imports System
Imports System.Security.Cryptography
Module Module1
Sub Main()
'Initialize the byte arrays to the public key information.
Dim PublicKey As Byte() = {214, 46, 220, 83, 160, 73, 40, 39, 201, 155, 19,202, 3, 11, 191, 178, 56, 74, 90, 36, 248, 103, 18, 144, 170, 163, 145, 87, 54, 61, 34, 220, 222, 207, 137, 149, 173, 14, 92, 120, 206, 222, 158, 28, 40, 24, 30, 16, 175, 108, 128, 35, 230, 118, 40, 121, 113, 125, 216, 130, 11, 24, 90, 48, 194, 240, 105, 44, 76, 34, 57, 249, 228, 125, 80, 38, 9, 136, 29, 117, 207, 139, 168, 181, 85, 137, 126, 10, 126, 242, 120, 247, 121, 8, 100, 12, 201, 171, 38, 226, 193, 180, 190, 117, 177, 87, 143, 242, 213, 11, 44, 180, 113, 93, 106, 99, 179, 68, 175, 211, 164, 116, 64, 148, 226, 254, 172, 147}
Dim Exponent As Byte() = {1, 0, 1}
'Create values to store encrypted symmetric keys.
Dim EncryptedSymmetricKey() As Byte
Dim EncryptedSymmetricIV() As Byte
'Create a new instance of the RSACryptoServiceProvider class.
Dim RSA As New RSACryptoServiceProvider()
'Create a new instance of the RSAParameters structure.
Dim RSAKeyInfo As New RSAParameters()
'Set RSAKeyInfo to the public key values.
RSAKeyInfo.Modulus = PublicKey
RSAKeyInfo.Exponent = Exponent
'Import key parameters into RSA.
RSA.ImportParameters(RSAKeyInfo)
'Create a new instance of the RijndaelManaged class.
Dim RM As New RijndaelManaged()
'Encrypt the symmetric key and IV.
EncryptedSymmetricKey = RSA.Encrypt(RM.Key, False)
EncryptedSymmetricIV = RSA.Encrypt(RM.IV, False)
End Sub
End Module
using System;
using System.Security.Cryptography;
class Class1
{
static void Main()
{
//Initialize the byte arrays to the public key information.
byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
106,99,179,68,175,211,164,116,64,148,226,254,172,147};
byte[] Exponent = {1,0,1};
//Create values to store encrypted symmetric keys.
byte[] EncryptedSymmetricKey;
byte[] EncryptedSymmetricIV;
//Create a new instance of the RSACryptoServiceProvider class.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
//Create a new instance of the RSAParameters structure.
RSAParameters RSAKeyInfo = new RSAParameters();
//Set RSAKeyInfo to the public key values.
RSAKeyInfo.Modulus = PublicKey;
RSAKeyInfo.Exponent = Exponent;
//Import key parameters into RSA.
RSA.ImportParameters(RSAKeyInfo);
//Create a new instance of the RijndaelManaged class.
RijndaelManaged RM = new RijndaelManaged();
//Encrypt the symmetric key and IV.
EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);
}
}
Vedere anche
Concetti
Generazione di chiavi per crittografia e decrittografia