Share via


Descifrar datos

El descifrado es la operación inversa del cifrado. En el cifrado de clave secreta debe conocer la clave y el IV (Inicialization Vector, vector de inicialización) utilizados para cifrar los datos. En el cifrado de clave pública debe conocer la clave pública (si los datos se cifraron con la clave privada) o la clave privada (si los datos se cifraron con la clave pública).

Descifrado simétrico

El descifrado de datos cifrados con algoritmos simétricos es similar al proceso utilizado para cifrar datos con algoritmos simétricos. La clase CryptoStream se utiliza con las clases de criptografía simétrica que proporciona .NET Framework para descifrar datos leídos de cualquier objeto de secuencia administrado.

En el ejemplo siguiente se ilustra cómo crear una nueva instancia de la clase RijndaelManaged y utilizarla para realizar el descifrado en un objeto CryptoStream. En este ejemplo primero se crea una nueva instancia de la clase RijndaelManaged. A continuación, se crea un objeto CryptoStream y se inicializa con el valor de una secuencia administrada denominada MyStream. Seguidamente, en el método CreateDecryptor de la clase RijndaelManaged se pasan la misma clave e IV que se utilizaron para el cifrado y, después, se pasan al constructor CryptoStream. Por último, la enumeración CryptoStreamMode.Read se pasa al constructor CryptoStream para especificar el acceso de lectura a la secuencia.

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);

En el ejemplo siguiente se muestra todo el proceso de creación, descifrado, lectura y cierre de las secuencias. Se crea un objeto TCPListener que inicializa una secuencia de red cuando se realiza una conexión con el objeto que está escuchando. A continuación, la secuencia de red se descifra utilizando las clases CryptoStream y RijndaelManaged. En este ejemplo se supone que los valores de clave e IV se han transferido correctamente o se han acordado previamente. No se muestra el código necesario para cifrar y transferir estos valores.

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.");
      }
   }
}

Para que el ejemplo anterior funcione, debe realizarse una conexión cifrada con el agente de escucha. La conexión debe utilizar la misma clave, IV y algoritmo empleados con el agente de escucha. Si se realiza esa conexión, el mensaje se descifra y aparece en la consola.

Descifrado asimétrico

Normalmente, una parte (parte A) genera tanto una clave pública como una clave privada y almacena la clave en memoria o en un contenedor de claves criptográficas. A continuación, la parte A envía la clave pública a otra parte (parte B). Usando la clave pública, la parte B cifra los datos y los vuelve a enviar a la parte A. Después de recibir los datos, la parte A los descifra usando la clave privada correspondiente. El descifrado sólo será correcto si la parte A utiliza la clave privada correspondiente a la clave pública que la parte B ha utilizado para cifrar los datos.

Para obtener información sobre cómo almacenar una clave asimétrica en un contenedor de claves criptográficas y cómo recuperar posteriormente la clave asimétrica, vea Cómo: Almacenar claves asimétricas en un contenedor de claves.

En el ejemplo siguiente se ilustra el descifrado de dos matrices de bytes que representan la clave simétrica y el IV. Para obtener información sobre cómo extraer la clave pública asimétrica del objeto RSACryptoServiceProvider en un formato que pueda enviarse con facilidad a terceros, vea Cifrar datos.

'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);

Vea también

Conceptos

Generar claves para cifrar y descifrar

Cifrar datos

Servicios criptográficos

Otros recursos

Tareas criptográficas