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


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

Обновлен: Ноябрь 2007

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

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

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

В следующем примере показано создание нового экземпляра класса RijndaelManaged и использование его для расшифровки объекта CryptoStream. Сначала создается новый экземпляр класса RijndaelManaged. Затем создается объект CryptoStream и инициализируется со значением управляемого потока MyStream. Далее метод CreateDecryptor класса RijndaelManaged получает те же самые ключ и вектор инициализации, что использовались при шифровании, а затем передается в конструктор CryptoStream. Наконец, перечисление CryptoStreamMode.Read передается конструктору CryptoStream, определяя доступ на чтение из потока.

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

В следующем примере показан весь процесс создания потока, расшифровки потока, осуществления чтения из потока и закрытия потока. Создается объект TCPListener, который инициализирует сетевой поток при подключении к объекту-прослушивателю. Затем сетевой поток расшифровывается с использованием классов CryptoStream и RijndaelManaged. В данном примере предполагается, что ключ и вектор инициализации были успешно переданы или согласованы заранее. Здесь не приводится код, выполняющий надежное шифрование и передачу ключа и вектора инициализации.

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

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

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

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

Сведения о хранении асимметричных ключей в безопасном контейнере криптографического ключа и их последующем извлечении см. в разделе Практическое руководство. Хранение асимметричных ключей в контейнере ключей.

В следующем примере демонстрируется расшифровка двух байтовых массивов, представляющих собой симметричный ключ и вектор инициализации. Сведения о способе извлечения асимметричного открытого ключа из объекта RSACryptoServiceProvider в формате, удобном для передачи третьей стороне, см. в разделе Шифрование данных.

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

См. также

Основные понятия

Создание ключей для шифрования и расшифровки

Шифрование данных

Другие ресурсы

Задачи криптографии

Службы криптографии