Verschlüsseln von Daten

Für die symmetrische und asymmetrische Verschlüsselung kommen unterschiedliche Prozesse zum Einsatz. Die symmetrische Verschlüsselung basiert auf Streams und ist daher für die Verschlüsselung großer Datenmengen geeignet. Bei der asymmetrischen Verschlüsselung wird jeweils nur eine kleine Bytezahl verschlüsselt. Sie eignet sich deshalb nur für kleine Datenmengen.

Symmetrische Verschlüsselung

Die verwalteten symmetrischen Kryptografieklassen werden mit einer speziellen Streamklasse mit dem Namen CryptoStream verwendet, die Daten im Stream verschlüsselt. Die CryptoStream-Klasse wird mit einer verwalteten Streamklasse initialisiert, durch die ihrerseits die ICryptoTransform-Schnittstelle (erstellt aus einer Klasse, durch die ein kryptografischer Algorithmus implementiert wird) und eine CryptoStreamMode-Enumeration implementiert wird, die die zulässige Art des Zugriffs auf die CryptoStream-Klasse beschreibt. Die CryptoStream-Klasse kann mit jeder Klasse, die sich von der Stream-Klasse ableitet, initialisiert werden. Dazu zählen auch die Klassen FileStream, MemoryStream und NetworkStream. Mit diesen Klassen können Sie die unterschiedlichsten Streamobjekte symmetrisch verschlüsseln.

Das folgende Beispiel veranschaulicht, wie eine neue Instanz der RijndaelManaged-Klasse, durch die der Rijndael-Verschlüsselungsalgorithmus implementiert wird, erstellt und zum Verschlüsseln einer CryptoStream-Klasse verwendet wird. In diesem Beispiel wird die CryptoStream-Klasse mit einem Streamobjekt mit dem Namen MyStream initialisiert, bei dem es sich um einen beliebigen Typ eines verwalteten Streams handeln kann. Der CreateEncryptor-Methode der RijndaelManaged-Klasse werden der Schlüssel und der Initialisierungsvektor (IV) übergeben, die für die Verschlüsselung benötigt werden. In diesem Fall wird der von RMCrypto erzeugte Standardschlüssel und IV verwendet. Zum Schluss wird CryptoStreamMode.Write übergeben und definiert den Schreibzugriff auf den Stream.

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

Nach der Ausführung dieses Codes werden alle in das CryptoStream-Objekt geschriebenen Daten mit dem Rijndael-Algorithmus verschlüsselt.

Das folgende Beispiel veranschaulicht den gesamten Prozess: das Erzeugen und Verschlüsseln des Streams, das Schreiben in den Stream und das Schließen des Streams. In diesem Beispiel wird ein Netzwerkstream erzeugt, der mit der CryptoStream-Klasse und der RijndaelManaged-Klasse verschlüsselt wird. Mit der StreamWriter-Klasse wird eine Nachricht in den verschlüsselten Stream geschrieben.

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

Damit das oben genannte Beispiel erfolgreich ausgeführt werden kann, muss es einen Prozess geben, der die in der TCPCLient-Klasse angegebene IP‑Adresse und Anschlussnummer überwacht. Wenn ein Listenerprozess existiert, stellt der Code eine Verbindung zu diesem Prozess her, verschlüsselt den Stream mit dem symmetrischen Rijndael-Algorithmus und schreibt Hello World in den Stream. Wenn der Code erfolgreich ausgeführt wurde, wird in der Konsole folgender Text angezeigt:

The message was sent.

Wenn jedoch kein Listenerprozess gefunden oder eine Ausnahme ausgelöst wurde, wird in der Konsole folgender Text angezeigt:

The connection failed.

Asymmetrische Verschlüsselung

Asymmetrische Algorithmen werden in der Regel zum Verschlüsseln kleiner Datenmengen, z. B. des symmetrischen Schlüssels und des Initialisierungsvektors (IV), verwendet. In der Regel wird bei einer asymmetrischen Verschlüsselung der von einem anderen Teilnehmer erzeugte öffentliche Schlüssel verwendet. Zu diesem Zweck wird von .NET Framework die RSACryptoServiceProvider-Klasse bereitgestellt.

Im folgenden Beispiel wird ein öffentlicher Schlüssel mit den entsprechenden Informationen zum Verschlüsseln eines symmetrischen Schlüssels und IVs verwendet. Zwei Bytearrays werden initialisiert, die den öffentlichen Schlüssel eines Dritten darstellen. Ein RSAParameters-Objekt wird mit diesen Werten initialisiert. Anschließend wird das RSAParameters-Objekt (und mit ihm der öffentliche Schlüssel) mit der RSACryptoServiceProvider.ImportParameters-Methode in eine RSACryptoServiceProvider-Klasse importiert. Zum Schluss werden der von einer RijndaelManaged-Klasse erstellte private Schlüssel und IV verschlüsselt. Dieses Beispiel gilt nur für Systeme mit 128-Bit-Verschlüsselung.

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

Siehe auch

Konzepte

Erzeugen von Schlüsseln für die Ver- und Entschlüsselung
Entschlüsseln von Daten

Weitere Ressourcen

Kryptografische Aufgaben
Kryptografische Dienste