Поделиться через


Расшифровка данных

Расшифровка представляет собой операцию, обратную операции шифрования. Для шифрования с секретным ключом необходимо знать как ключ, так и вектор инициализации, которые использовались при шифровании данных. Для шифрования с открытым ключом необходимо знать либо открытый ключ (если данные были зашифрованы при помощи закрытого ключа), либо закрытый ключ (если данные были зашифрованы при помощи открытого ключа).

Симметричная расшифровка

Расшифровка данных, зашифрованных при помощи симметричных алгоритмов, похожа на процесс, используемый для шифрования данных при помощи симметричных алгоритмов. Класс CryptoStream используется с симметричными классами шифрования, предоставляемыми .NET для расшифровки данных из любого управляемого объекта потока.

В следующем примере показано, как создать новый экземпляр класса реализации по умолчанию для алгоритма Aes . Экземпляр используется для расшифровки CryptoStream объекта. В этом примере сначала создается новый экземпляр Aes класса реализации. Он считывает значение вектора инициализации (IV) из переменной управляемого потока. fileStream Затем он создает экземпляр CryptoStream объекта и инициализирует его в значение экземпляра fileStream . Метод SymmetricAlgorithm.CreateDecryptor из экземпляра Aes передается значение IV и тот же ключ, который использовался для шифрования.

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

В следующем примере показан весь процесс создания потока, расшифровки потока, чтения из потока и закрытия потока. Создается объект потока файлов, который считывает файл с именем TestData.txt. Затем поток файлов расшифровывается с помощью класса CryptoStream и класса Aes . В этом примере указывается значение ключа, используемое в примере симметричного шифрования для шифрования данных. Он не показывает код, необходимый для шифрования и передачи этих значений.

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

В предыдущем примере используется тот же ключ и алгоритм, используемый в примере симметричного шифрования для шифрования данных. Он расшифровывает файл TestData.txt , созданный этим примером, и отображает исходный текст в консоли.

Асимметричное расшифровка

Как правило, сторона (сторона А) создает как открытый, так и закрытый ключи и сохраняет их в памяти или в контейнере криптографических ключей. Затем сторона А пересылает открытый ключ другой стороне (сторона Б). С помощью открытого ключа сторона Б шифрует данные и отправляет их обратно стороне А. Получив данные, сторона А расшифровывает их с помощью соответствующего закрытого ключа. Расшифровка будет успешной только в том случае, если сторона А использует закрытый ключ, соответствующий открытому ключу, использованному стороной Б для шифрования данных.

Дополнительные сведения о хранении асимметричных ключей в безопасном контейнере криптографических ключей и последующем извлечении асимметричного ключа см. в разделе How to: Store Asymmetric Keys in a Key Container.

Следующий пример иллюстрирует расшифровку двух массивов байтов, представляющих симметричный ключ и вектор инициализации. Дополнительные сведения о способе извлечения асимметричного открытого ключа из объекта RSA в формате, допускающем простую отправку третьей стороне, см. в разделе 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);

См. также