Descifrado de datos

El descifrado es la operación inversa del cifrado. Para el cifrado de clave secreta, debe conocer la clave y el IV que se usaron para cifrar los datos. Para el cifrado de clave pública, debe conocer la clave pública (si los datos se cifraron mediante la clave privada) o la clave privada (si los datos se cifran mediante la clave pública).

Descifrado simétrico

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

En el ejemplo siguiente se muestra cómo crear una nueva instancia de la clase de implementación predeterminada del algoritmo Aes. La instancia se usa para realizar el descifrado en un objeto CryptoStream. En primer lugar, en este ejemplo se crea una nueva instancia de la clase de implementación Aes. Lee el valor del vector de inicialización (IV) de una variable de secuencia administrada, fileStream. A continuación, crea una instancia de un objeto CryptoStream y la inicializa en el valor de la instancia fileStream. Al método SymmetricAlgorithm.CreateDecryptor de la instancia Aes se le pasa el valor del vector de inicialización y la misma clave usada para el cifrado.

Dim aes As Aes = Aes.Create()
Dim cryptStream As New CryptoStream(
    fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)
Aes aes = Aes.Create();
CryptoStream cryptStream = new CryptoStream(
    fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read);

En el ejemplo siguiente se muestra todo el proceso de crear una secuencia, descifrarla, leer en ella y cerrarla. Se crea un objeto de secuencia de archivos que lee un archivo de nombre TestData.txt. Luego, la secuencia de archivos se descifra mediante las clases CryptoStream y Aes. En este ejemplo se especifica el valor de clave que se usa en el ejemplo de cifrado simétrico de Cifrado de datos. No se muestra el código necesario para cifrar y transferir estos valores.

using System.Security.Cryptography;

try
{
    using (FileStream fileStream = new("TestData.txt", FileMode.Open))
    {
        using (Aes aes = Aes.Create())
        {
            byte[] iv = new byte[aes.IV.Length];
            int numBytesToRead = aes.IV.Length;
            int numBytesRead = 0;
            while (numBytesToRead > 0)
            {
                int n = fileStream.Read(iv, numBytesRead, numBytesToRead);
                if (n == 0) break;

                numBytesRead += n;
                numBytesToRead -= n;
            }

            byte[] key =
            {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
            };

            using (CryptoStream cryptoStream = new(
               fileStream,
               aes.CreateDecryptor(key, iv),
               CryptoStreamMode.Read))
            {
                // By default, the StreamReader uses UTF-8 encoding.
                // To change the text encoding, pass the desired encoding as the second parameter.
                // For example, new StreamReader(cryptoStream, Encoding.Unicode).
                using (StreamReader decryptReader = new(cryptoStream))
                {
                    string decryptedMessage = await decryptReader.ReadToEndAsync();
                    Console.WriteLine($"The decrypted original message: {decryptedMessage}");
                }
            }
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine($"The decryption failed. {ex}");
}
Imports System
Imports System.IO
Imports System.Security.Cryptography

Module Module1
    Sub Main()
        ' Decryption key must be the same value that was 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}

        Try
            ' Create a file stream.
            Using fileStream As New FileStream("TestData.txt", FileMode.Open)

                ' Create a new instance of the default Aes implementation class
                Using aes As Aes = Aes.Create()

                    ' Reads IV value from beginning of the file.
                    Dim iv As Byte() = New Byte(aes.IV.Length - 1) {}
                    Dim numBytesToRead As Integer = CType(aes.IV.Length, Integer)
                    Dim numBytesRead As Integer = 0

                    While (numBytesToRead > 0)
                        Dim n As Integer = fileStream.Read(iv, numBytesRead, numBytesToRead)
                        If n = 0 Then
                            Exit While
                        End If
                        numBytesRead += n
                        numBytesToRead -= n
                    End While

                    Using cryptoStream As New CryptoStream(fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)

                        ' By default, the StreamReader uses UTF-8 encoding.
                        ' To change the text encoding, pass the desired encoding as the second parameter.
                        ' For example, New StreamReader(cryptoStream, Encoding.Unicode).
                        Using decryptReader As New StreamReader(cryptoStream)

                            ' Display the message.
                            Console.WriteLine($"The decrypted original message: {decryptReader.ReadToEnd()}")
                        End Using
                    End Using
                End Using
            End Using
        Catch
            Console.WriteLine("The decryption Failed.")
            Throw
        End Try
    End Sub
End Module

En el ejemplo anterior se usan la misma clave y el algoritmo usados en el ejemplo de cifrado simétrico de Cifrado de datos. Descifra el archivo TestData.txt creado por ese ejemplo y muestra el texto original en la consola.

Descifrado asimétrico

Normalmente, una parte (parte A) genera tanto una clave pública como privada y la almacena 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). Con la clave pública, la parte B cifra los datos y los envía de vuelta a la parte A. Después de recibir los datos, la parte A los descifra con la clave privada correspondiente. El descifrado será correcto solo si la parte A usa la clave privada que corresponde a la clave pública que la parte B usó para cifrar los datos.

Para obtener información sobre cómo almacenar una clave asimétrica en un contenedor de claves criptográficas seguro y cómo recuperar posteriormente la clave asimétrica, consulte How to: Store Asymmetric Keys in a Key Container.

En el ejemplo siguiente se muestra el descifrado de dos matrices de bytes que representan una clave simétrica y un IV. Para obtener información sobre cómo extraer la clave pública asimétrica del objeto RSA en un formato que se pueda enviar fácilmente a un tercero, consulte Encrypting Data.

'Create a new instance of the RSA class.
Dim rsa As RSA = RSA.Create()

' 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, RSAEncryptionPadding.Pkcs1)
symmetricIV = rsa.Decrypt(encryptedSymmetricIV, RSAEncryptionPadding.Pkcs1)
//Create a new instance of the RSA class.
RSA rsa = RSA.Create();

// 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, RSAEncryptionPadding.Pkcs1);
symmetricIV = rsa.Decrypt(encryptedSymmetricIV , RSAEncryptionPadding.Pkcs1);

Consulte también