Condividi tramite


Decrittografia di dati

Aggiornamento: novembre 2007

La decrittografia è l'operazione inversa rispetto alla crittografia. Per la crittografia a chiave segreta è necessario conoscere sia la chiave che il vettore di inizializzazione utilizzati per crittografare i dati. Per la crittografia a chiave pubblica è necessario conoscere la chiave pubblica, se i dati sono stati crittografati con la chiave privata, o la chiave privata, se i dati sono stati crittografati con la chiave pubblica.

Decrittografia simmetrica

La decrittografia dei dati crittografati con gli algoritmi simmetrici è simile al processo utilizzato per crittografare i dati con algoritmi simmetrici. La classe CryptoStream viene utilizzata con le classi di crittografia simmetrica disponibili in .NET Framework per decrittografare i dati letti da qualsiasi oggetto flusso gestito.

Nell'esempio riportato di seguito viene illustrato come creare una nuova istanza della classe RijndaelManaged e come utilizzarla per eseguire la decrittografia su un oggetto CryptoStream. In questo esempio viene prima creata una nuova istanza della classe RijndaelManaged. Successivamente, viene creato un oggetto CryptoStream, inizializzato sul valore di un flusso gestito denominato MyStream. Al metodo CreateDecryptor della classe RijndaelManaged vengono quindi passati la stessa chiave e lo stesso vettore di inizializzazione utilizzati per la crittografia. A questo punto il metodo viene passato al costruttore CryptoStream. Infine l'enumerazione CryptoStreamMode.Read viene passata al costruttore CryptoStream per specificare l'accesso in lettura al flusso.

Dim RMCrypto As New RijndaelManaged()
Dim CryptStream As New CryptoStream(MyStream, RMCrypto.CreateDecryptor(RMCrypto.Key, RMCrypto.IV), CryptoStreamMode.Read)
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream CryptStream = new CryptoStream(MyStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read);

Nell'esempio che segue viene illustrato l'intero processo di creazione di un flusso, di decrittografia del flusso, di lettura dal flusso e di chiusura del flusso. Viene creato un oggetto TCPListener che inizializza un flusso di rete quando viene effettuata una connessione all'oggetto in ascolto. Il flusso di rete viene quindi decrittografato utilizzando la classe CryptoStream e la classe RijndaelManaged. In questo esempio si presuppone che i valori della chiave e del vettore di inizializzazione siano stati trasferiti in modo corretto o siano stati precedentemente concordati. Non viene mostrato il codice necessario per la crittografia e il trasferimento di questi valori.

Imports System
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Imports System.Net
Imports System.Security.Cryptography

Module Module1
    Sub Main()
            'The key and IV must be the same values that were used
            'to encrypt the stream.  
            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}
        Try
            'Initialize a TCPListener on port 11000
            'using the current IP address.
            Dim TCPListen As New TcpListener(IPAddress.Any, 11000)

            'Start the listener.
            TCPListen.Start()

            'Check for a connection every five seconds.
            While Not TCPListen.Pending()
                Console.WriteLine("Still listening. Will try in 5 seconds.")

                Thread.Sleep(5000)
            End While

            'Accept the client if one is found.
            Dim TCP As TcpClient = TCPListen.AcceptTcpClient()

            'Create a network stream from the connection.
            Dim NetStream As NetworkStream = TCP.GetStream()

            'Create a new instance of the RijndaelManaged class
            'and decrypt the stream.
            Dim RMCrypto As New RijndaelManaged()


            'Create an instance of the CryptoStream class, pass it the NetworkStream, and decrypt 
            'it with the Rijndael class using the key and IV.
            Dim CryptStream As New CryptoStream(NetStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read)

            'Read the stream.
            Dim SReader As New StreamReader(CryptStream)

            'Display the message.
            Console.WriteLine("The decrypted original message: {0}", SReader.ReadToEnd())

            'Close the streams.
            SReader.Close()
            NetStream.Close()
            TCP.Close()
            'Catch any exceptions. 
        Catch
            Console.WriteLine("The Listener Failed.")
        End Try
    End Sub
End Module
using System;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net;
using System.Security.Cryptography;

class Class1
{
   static void Main(string[] args)
   {
      //The key and IV must be the same values that were used
      //to encrypt the stream.  
      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};
      try
      {
         //Initialize a TCPListener on port 11000
         //using the current IP address.
         TcpListener TCPListen = new TcpListener(IPAdress.Any, 11000);

         //Start the listener.
         TCPListen.Start();

         //Check for a connection every five seconds.
         while(!TCPListen.Pending())
         {
            Console.WriteLine("Still listening. Will try in 5 seconds.");
            Thread.Sleep(5000);
         }

         //Accept the client if one is found.
         TcpClient TCP = TCPListen.AcceptTcpClient();

         //Create a network stream from the connection.
         NetworkStream NetStream = TCP.GetStream();

         //Create a new instance of the RijndaelManaged class
         // and decrypt the stream.
         RijndaelManaged RMCrypto = new RijndaelManaged();


         //Create a CryptoStream, pass it the NetworkStream, and decrypt 
         //it with the Rijndael class using the key and IV.
         CryptoStream CryptStream = new CryptoStream(NetStream, 
            RMCrypto.CreateDecryptor(Key, IV), 
            CryptoStreamMode.Read);

         //Read the stream.
         StreamReader SReader = new StreamReader(CryptStream);

         //Display the message.
         Console.WriteLine("The decrypted original message: {0}", SReader.ReadToEnd());

         //Close the streams.
         SReader.Close();
         NetStream.Close();
         TCP.Close();
      }
      //Catch any exceptions. 
      catch
      {
         Console.WriteLine("The Listener Failed.");
      }
   }
}

Perché l'esempio precedente possa funzionare, è necessario effettuare una connessione crittografata al listener. La connessione deve utilizzare la stessa chiave, vettore di inizializzazione e algoritmo utilizzati nel listener. Se viene effettuata una connessione del genere, il messaggio verrà decrittografato e visualizzato nella console.

Decrittografia asimmetrica

In genere una parte, ad esempio la parte A, genera una chiave pubblica e una privata e le archivia in memoria oppure in un contenitore di chiavi crittografico, quindi invia la chiave pubblica a un'altra parte, ovvero la parte B. Mediante la chiave pubblica, la parte B crittografa i dati e li invia nuovamente alla parte A che, dopo averli ricevuti, ne esegue la decrittografia mediante la chiave privata appropriata. La decrittografia avrà esito positivo solo se la parte A utilizza la chiave privata corrispondente alla chiave pubblica utilizzata dalla parte B per crittografare i dati.

Per informazioni su come archiviare una chiave asimmetrica in un contenitore di chiavi crittografico protetto e su come recuperarla successivamente, vedere Procedura: archiviare chiavi asimmetriche in un contenitore di chiavi.

Nell'esempio che segue viene illustrata la decrittografia di due matrici di byte che rappresenta una chiave simmetrica e un vettore di inizializzazione. Per informazioni su come estrarre la chiave pubblica asimmetrica dall'oggetto RSACryptoServiceProvider in un formato semplice da inviare a una terza parte, vedere Crittografia dei dati.

'Create a new instance of the RSACryptoServiceProvider class.
Dim RSA As New RSACryptoServiceProvider()

' Export the public key information and send it to a third party.
' Wait for the third party to encrypt some data and send it back.

'Decrypt the symmetric key and IV.
SymmetricKey = RSA.Decrypt(EncryptedSymmetricKey, False)
SymmetricIV = RSA.Decrypt(EncryptedSymmetricIV, False)
//Create a new instance of the RSACryptoServiceProvider class.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

// Export the public key information and send it to a third party.
// Wait for the third party to encrypt some data and send it back.

//Decrypt the symmetric key and IV.
SymmetricKey = RSA.Decrypt( EncryptedSymmetricKey, false);
SymmetricIV = RSA.Decrypt( EncryptedSymmetricIV , false);

Vedere anche

Concetti

Generazione di chiavi per crittografia e decrittografia

Crittografia dei dati

Altre risorse

Attività di crittografia

Servizi di crittografia