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


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

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

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

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

Управляемые классы симметричного шифрования используются со специальным классом потока CryptoStream, который осуществляет шифрование считываемых из потока данных. Класс CryptoStream инициализируется с помощью управляемого класса потока, реализующего интерфейс ICryptoTransform (созданный на основе класса, реализующего криптографический алгоритм), а также перечисления CryptoStreamMode, определяющего разрешенный тип доступа к CryptoStream. Класс CryptoStream может быть инициализирован с помощью любого класса, производного от класса Stream, включая FileStream, MemoryStream и NetworkStream. С помощью этих классов можно легко осуществлять симметричное шифрование различных потоковых объектов.

В следующем примере показано, как создать новый экземпляр класса RijndaelManaged, реализующего алгоритм шифрования Rijndael, и использовать его для шифрования класса CryptoStream. В этом примере CryptoStream инициализируется с помощью объекта потока MyStream, который может являться любым типом управляемого потока. Метод CreateEncryptor класса RijndaelManaged получает значения ключа и вектора инициализации, которые используются для шифрования. В данном случае используются значения ключа и вектора инициализации, создаваемые по умолчанию из RMCrypto. И наконец передается CryptoStreamMode.Write, определяя разрешение на запись в поток.

Dim RMCrypto As New RijndaelManaged()
Dim CryptStream As New CryptoStream(MyStream, RMCrypto.CreateEncryptor(RMCrypto.Key, RMCrypto.IV), CryptoStreamMode.Write)
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream CryptStream = new CryptoStream(MyStream, RMCrypto.CreateEncryptor(), CryptoStreamMode.Write);

После выполнения этого кода любые данные, записываемые в объект CryptoStream, зашифровываются с помощью алгоритма Rijndael.

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

Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Net.Sockets

Module Module1
Sub Main()
   Try
      'Create a TCP connection to a listening TCP process.
      'Use "localhost" to specify the current computer or
      'replace "localhost" with the IP address of the 
      'listening process. 
      Dim TCP As New TcpClient("localhost", 11000)

      'Create a network stream from the TCP connection. 
      Dim NetStream As NetworkStream = TCP.GetStream()

      'Create a new instance of the RijndaelManaged class
      'and encrypt the stream.
      Dim RMCrypto As New RijndaelManaged()

            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}

      'Create a CryptoStream, pass it the NetworkStream, and encrypt 
      'it with the Rijndael class.
      Dim CryptStream As New CryptoStream(NetStream, RMCrypto.CreateEncryptor(Key, IV), CryptoStreamMode.Write)

      'Create a StreamWriter for easy writing to the 
      'network stream.
      Dim SWriter As New StreamWriter(CryptStream)

      'Write to the stream.
      SWriter.WriteLine("Hello World!")

      'Inform the user that the message was written
      'to the stream.
      Console.WriteLine("The message was sent.")

      'Close all the connections.
      SWriter.Close()
      CryptStream.Close()
      NetStream.Close()
      TCP.Close()
   Catch
      'Inform the user that an exception was raised.
      Console.WriteLine("The connection failed.")
   End Try
End Sub
End Module
using System;
using System.IO;
using System.Security.Cryptography;
using System.Net.Sockets;
 
public class main
{
   public static void Main(string[] args)
   {
      try
      {
         //Create a TCP connection to a listening TCP process.
         //Use "localhost" to specify the current computer or
         //replace "localhost" with the IP address of the 
         //listening process.  
         TcpClient TCP = new TcpClient("localhost",11000);
   
         //Create a network stream from the TCP connection. 
         NetworkStream NetStream = TCP.GetStream();

         //Create a new instance of the RijndaelManaged class
         // and encrypt the stream.
         RijndaelManaged RMCrypto = new RijndaelManaged();

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

         //Create a CryptoStream, pass it the NetworkStream, and encrypt 
         //it with the Rijndael class.
         CryptoStream CryptStream = new CryptoStream(NetStream, 
         RMCrypto.CreateEncryptor(Key, IV),   
         CryptoStreamMode.Write);

         //Create a StreamWriter for easy writing to the 
         //network stream.
         StreamWriter SWriter = new StreamWriter(CryptStream);

         //Write to the stream.
         SWriter.WriteLine("Hello World!");

         //Inform the user that the message was written
         //to the stream.
         Console.WriteLine("The message was sent.");

         //Close all the connections.
         SWriter.Close();
         CryptStream.Close();
         NetStream.Close();
         TCP.Close();
      }
      catch
      {
         //Inform the user that an exception was raised.
         Console.WriteLine("The connection failed.");
      }
   }
}

Для успешного выполнения приведенного выше кода необходимо, чтобы существовал процесс прослушивания IP-адреса и порта, указанных в классе TCPCLient. Если такой процесс существует, код выполняет подключение к процессу прослушивателя, зашифровывает поток с помощью симметричного алгоритма Rijndael и записывает в этот поток сообщение "Hello World!". В случае успешного выполнения на консоль выводится следующий текст:

The message was sent.

Однако если указанный процесс не найден или возникло исключение, на консоль выводится следующий текст:

The connection failed.

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

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

В следующем примере сведения об открытом ключе используются для шифрования симметричного ключа и вектора инициализации. Инициализируются два байтовых массива, представляющих собой открытый ключ третьей стороны. Эти значения используются для инициализации объекта RSAParameters. Далее объект RSAParameters (и открытый ключ, который он представляет) импортируется в RSACryptoServiceProvider с помощью метода RSACryptoServiceProvider.ImportParameters. Наконец, осуществляется шифрование закрытого ключа и вектора инициализации, созданных классом RijndaelManaged. Выполнение кода из следующего примера требует, чтобы в системе была установлена поддержка 128-битного шифрования.

Imports System
Imports System.Security.Cryptography

Module Module1

    Sub Main()
        'Initialize the byte arrays to the public key information.
      Dim PublicKey As Byte() =  {214, 46, 220, 83, 160, 73, 40, 39, 201, 155, 19,202, 3, 11, 191, 178, 56, 74, 90, 36, 248, 103, 18, 144, 170, 163, 145, 87, 54, 61, 34, 220, 222, 207, 137, 149, 173, 14, 92, 120, 206, 222, 158, 28, 40, 24, 30, 16, 175, 108, 128, 35, 230, 118, 40, 121, 113, 125, 216, 130, 11, 24, 90, 48, 194, 240, 105, 44, 76, 34, 57, 249, 228, 125, 80, 38, 9, 136, 29, 117, 207, 139, 168, 181, 85, 137, 126, 10, 126, 242, 120, 247, 121, 8, 100, 12, 201, 171, 38, 226, 193, 180, 190, 117, 177, 87, 143, 242, 213, 11, 44, 180, 113, 93, 106, 99, 179, 68, 175, 211, 164, 116, 64, 148, 226, 254, 172, 147}

        Dim Exponent As Byte() = {1, 0, 1}

        'Create values to store encrypted symmetric keys.
        Dim EncryptedSymmetricKey() As Byte
        Dim EncryptedSymmetricIV() As Byte

        'Create a new instance of the RSACryptoServiceProvider class.
        Dim RSA As New RSACryptoServiceProvider()

        'Create a new instance of the RSAParameters structure.
        Dim RSAKeyInfo As New RSAParameters()

        'Set RSAKeyInfo to the public key values. 
        RSAKeyInfo.Modulus = PublicKey
        RSAKeyInfo.Exponent = Exponent

        'Import key parameters into RSA.
        RSA.ImportParameters(RSAKeyInfo)

        'Create a new instance of the RijndaelManaged class.
        Dim RM As New RijndaelManaged()

        'Encrypt the symmetric key and IV.
        EncryptedSymmetricKey = RSA.Encrypt(RM.Key, False)
        EncryptedSymmetricIV = RSA.Encrypt(RM.IV, False)
    End Sub

End Module
using System;
using System.Security.Cryptography;

class Class1
{
   static void Main()
   {
      //Initialize the byte arrays to the public key information.
      byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
            74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
            207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
            108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
            240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
            168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
            38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
            106,99,179,68,175,211,164,116,64,148,226,254,172,147};

      byte[] Exponent = {1,0,1};
      
      //Create values to store encrypted symmetric keys.
      byte[] EncryptedSymmetricKey;
      byte[] EncryptedSymmetricIV;

      //Create a new instance of the RSACryptoServiceProvider class.
      RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

      //Create a new instance of the RSAParameters structure.
      RSAParameters RSAKeyInfo = new RSAParameters();

      //Set RSAKeyInfo to the public key values. 
      RSAKeyInfo.Modulus = PublicKey;
      RSAKeyInfo.Exponent = Exponent;

      //Import key parameters into RSA.
      RSA.ImportParameters(RSAKeyInfo);

      //Create a new instance of the RijndaelManaged class.
      RijndaelManaged RM = new RijndaelManaged();

      //Encrypt the symmetric key and IV.
      EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
      EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);
   }
}

См. также

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

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

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

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

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

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