Odszyfrowywanie danych

Odszyfrowywanie to odwrotna operacja szyfrowania. W przypadku szyfrowania kluczem tajnym musisz znać zarówno klucz, jak i IV, który został użyty do szyfrowania danych. W przypadku szyfrowania klucza publicznego musisz znać klucz publiczny (jeśli dane zostały zaszyfrowane przy użyciu klucza prywatnego) lub klucz prywatny (jeśli dane zostały zaszyfrowane przy użyciu klucza publicznego).

Odszyfrowywanie symetryczne

Odszyfrowywanie danych zaszyfrowanych za pomocą algorytmów symetrycznych jest podobne do procesu szyfrowania danych za pomocą algorytmów symetrycznych. Klasa CryptoStream jest używana z symetrycznymi klasami kryptografii udostępnianymi przez platformę .NET do odszyfrowywania danych odczytywanych z dowolnego obiektu zarządzanego strumienia.

W poniższym przykładzie pokazano, jak utworzyć nowe wystąpienie domyślnej klasy implementacji dla algorytmu Aes . Wystąpienie służy do odszyfrowywania obiektu CryptoStream . Ten przykład najpierw tworzy nowe wystąpienie klasy implementacji Aes . Odczytuje wartość wektora inicjowania (IV) ze zmiennej zarządzanego strumienia . fileStream Następnie tworzy wystąpienie CryptoStream obiektu i inicjuje go do wartości fileStream wystąpienia. Metoda SymmetricAlgorithm.CreateDecryptor z Aes wystąpienia jest przekazywana wartość IV i ten sam klucz, który został użyty do szyfrowania.

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

Poniższy przykład przedstawia cały proces tworzenia strumienia, odszyfrowywania strumienia, odczytywania ze strumienia i zamykania strumieni. Tworzony jest obiekt strumienia plików, który odczytuje plik o nazwie TestData.txt. Strumień plików jest następnie odszyfrowywane przy użyciu klasy CryptoStream i klasy Aes . W tym przykładzie określono wartość klucza, która jest używana w przykładzie szyfrowania symetrycznego dla szyfrowania danych. Nie pokazuje on kodu potrzebnego do szyfrowania i transferu tych wartości.

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

W poprzednim przykładzie użyto tego samego klucza i algorytmu używanego w przykładzie szyfrowania symetrycznego w przypadku szyfrowania danych. Odszyfrowuje plik TestData.txt utworzony przez ten przykład i wyświetla oryginalny tekst w konsoli programu .

Odszyfrowywanie asymetryczne

Zazwyczaj strona (strona A) generuje zarówno klucz publiczny, jak i prywatny oraz przechowuje klucz w pamięci lub w kontenerze kluczy kryptograficznych. Strona A następnie wysyła klucz publiczny do innej strony (strona B). Korzystając z klucza publicznego, strona B szyfruje dane i wysyła dane z powrotem do strony A. Po otrzymaniu danych strona A odszyfrowuje je przy użyciu klucza prywatnego, który odpowiada. Odszyfrowywanie zakończy się powodzeniem tylko wtedy, gdy strona A używa klucza prywatnego odpowiadającego kluczowi publicznemu B używanemu do szyfrowania danych.

Aby uzyskać informacje na temat przechowywania klucza asymetrycznego w bezpiecznym kontenerze kluczy kryptograficznych i sposobie późniejszego pobierania klucza asymetrycznego, zobacz Jak przechowywać klucze asymetryczne w kontenerze kluczy.

Poniższy przykład ilustruje odszyfrowywanie dwóch tablic bajtów reprezentujących klucz symetryczny i IV. Aby uzyskać informacje na temat wyodrębniania asymetrycznego klucza publicznego z RSA obiektu w formacie, który można łatwo wysłać do innej firmy, zobacz Szyfrowanie danych.

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

Zobacz też