Freigeben über


.NET-Kryptografiemodell

.NET Framework stellt Implementierungen von zahlreichen Standardkryptografiealgorithmen bereit.

Objektvererbung

Das .NET-Kryptografiemodell implementiert ein erweiterbares Muster der abgeleiteten Klassenvererbung. Die Hierarchie lautet wie folgt:

Mit diesem Muster abgeleiteter Klassen können Sie einen neuen Algorithmus oder eine neue Implementierung eines vorhandenen Algorithmus hinzufügen. Möchten Sie z. B. einen neuen Algorithmus für einen öffentlichem Schlüssel erstellen, würden Sie von der AsymmetricAlgorithm-Klasse erben. Um eine neue Implementierung eines bestimmten Algorithmus zu erstellen, würden Sie eine nicht abstrakte abgeleitete Klasse dieses Algorithmus erstellen.

Dieses Vererbungsmodell wird künftig nicht für neue Arten von Primitiven wie AesGcm oder Shake128 verwendet. Diese Algorithmen sind vom Typ sealed. Wenn Sie ein Erweiterbarkeitsmuster oder eine Abstraktion dieser Typen benötigen, liegt die Implementierung der Abstraktion in der Verantwortung des Entwicklers oder der Entwicklerin.

Einmal-APIs

In .NET 5 wurden einfachere APIs für Hashing und HMAC eingeführt. Diese Einmal-APIs sind zwar etwas weniger flexibel, bieten aber folgende Vorteile:

  • Sie sind einfacher zu verwenden (und weniger anfällig für Missbrauch).
  • Sie reduzieren Zuteilungen oder sind zuordnungsfrei.
  • Sie sind threadsicher.
  • Sie verwenden die beste verfügbare Implementierung für die Plattform.

Die Hashing- und HMAC-Primitiven machen eine Einmal-API über eine statische HashData-Methode für den Typ verfügbar, z. B. SHA256.HashData. Die statischen APIs bieten keinen integrierten Erweiterungsmechanismus. Wenn Sie Ihre eigenen Algorithmen implementieren, empfiehlt es sich, auch ähnliche statische APIs des Algorithmus anzubieten.

Die RandomNumberGenerator-Klasse bietet ebenfalls statische Methoden zum Erstellen oder Füllen von Puffern mit kryptografischen Zufallsdaten. Diese Methoden verwenden immer den CSPRNG (Cryptographically Secure Pseudo-Random Number Generator, kryptographisch sicherer Zufallszahlengenerator) des Systems.

Implementierung von Algorithmen in .NET

Als ein Beispiel für die verschiedenen Implementierungen eines Algorithmus können Sie sich symmetrische Algorithmen ansehen. Die Basis für alle symmetrischen Algorithmen ist die SymmetricAlgorithm-Klasse, die von Aes, TripleDES und anderen geerbt wird, die nicht mehr empfohlen werden.

Aes wird geerbt von AesCryptoServiceProvider, AesCng und AesManaged.

In .NET Framework unter Windows:

  • *CryptoServiceProvider-Algorithmusklassen, z. B. AesCryptoServiceProvider, sind Wrapper um die CAPI-Implementierung (Windows Cryptography API) eines Algorithmus.
  • *Cng-Algorithmusklassen, z. B. ECDiffieHellmanCng, sind Wrapper um die CNG-Implementierung (Windows Cryptography Next Generation).
  • *Managed-Klassen, z. B. AesManaged, werden vollständig in verwaltetem Code geschrieben. Die *Managed-Implementierungen sind nicht durch die FIPS (Federal Information Processing Standards) zertifiziert und möglicherweise langsamer als die Wrapperklassen *CryptoServiceProvider und *Cng.

In .NET Core und .NET 5 und höheren Versionen sind alle Implementierungsklassen (*CryptoServiceProvider, *Managed und *Cng) Wrapper für die Betriebssystemalgorithmen. Sind die Betriebssystemalgorithmen FIPS-zertifiziert, werden von .NET FIPS-zertifizierte Algorithmen verwendet. Weitere Informationen finden Sie unter Plattformübergreifende Kryptografie.

In den meisten Fällen müssen Sie nicht direkt auf eine Algorithmusimplementierungsklasse wie AesCryptoServiceProvider verweisen. Die Methoden und Eigenschaften, die Sie normalerweise benötigen, befinden sich in der Basisalgorithmusklasse, z. B. Aes. Erstellen Sie eine Instanz einer Standardimplementierungsklasse mithilfe einer Factorymethode für die Basisalgorithmusklasse, und verweisen Sie auf die Basisalgorithmusklasse. Sehen Sie sich beispielsweise die hervorgehobene Codezeile im folgenden Beispiel an:

using System.Security.Cryptography;

try
{
    using (FileStream fileStream = new("TestData.txt", FileMode.OpenOrCreate))
    {
        using (Aes aes = Aes.Create())
        {
            byte[] key =
            {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
            };
            aes.Key = key;

            byte[] iv = aes.IV;
            fileStream.Write(iv, 0, iv.Length);

            using (CryptoStream cryptoStream = new(
                fileStream,
                aes.CreateEncryptor(),
                CryptoStreamMode.Write))
            {
                // By default, the StreamWriter uses UTF-8 encoding.
                // To change the text encoding, pass the desired encoding as the second parameter.
                // For example, new StreamWriter(cryptoStream, Encoding.Unicode).
                using (StreamWriter encryptWriter = new(cryptoStream))
                {
                    encryptWriter.WriteLine("Hello World!");
                }
            }
        }
    }

    Console.WriteLine("The file was encrypted.");
}
catch (Exception ex)
{
    Console.WriteLine($"The encryption failed. {ex}");
}
Imports System
Imports System.IO
Imports System.Security.Cryptography

Module Module1
    Sub Main()
        Try
            ' Create a file stream
            Using fileStream As New FileStream("TestData.txt", FileMode.OpenOrCreate)

                ' Create a new instance of the default Aes implementation class  
                ' and configure encryption key.
                Using aes As Aes = Aes.Create()
                    'Encryption key used to encrypt the stream.
                    'The same value must be used to encrypt and decrypt the stream.
                    Dim key As Byte() = {
                        &H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8,
                        &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16
                    }

                    aes.Key = key

                    ' Stores IV at the beginning of the file.
                    ' This information will be used for decryption.
                    Dim iv As Byte() = aes.IV
                    fileStream.Write(iv, 0, iv.Length)

                    ' Create a CryptoStream, pass it the FileStream, and encrypt
                    ' it with the Aes class.
                    Using cryptoStream As New CryptoStream(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write)

                        ' By default, the StreamWriter uses UTF-8 encoding.
                        ' To change the text encoding, pass the desired encoding as the second parameter.
                        ' For example, New StreamWriter(cryptoStream, Encoding.Unicode).
                        Using sWriter As New StreamWriter(cryptoStream)

                            'Write to the stream.
                            sWriter.WriteLine("Hello World!")
                        End Using
                    End Using
                End Using
            End Using

            'Inform the user that the message was written  
            'to the stream.  
            Console.WriteLine("The text was encrypted.")
        Catch
            'Inform the user that an exception was raised.  
            Console.WriteLine("The encryption failed.")
            Throw
        End Try
    End Sub
End Module

Auswählen eines Algorithmus

Sie können einen Algorithmus für unterschiedliche Zwecke wählen: z. B. für Datenintegrität, für Datenschutz oder zum Generieren eines Schlüssels. Symmetrische und Hashalgorithmen sind dazu vorgesehen, Daten entweder aus Integritätsgründen (Schutz vor Änderungen) oder aus Datenschutzgründen (Schutz vor Anzeigen) zu schützen. Hashalgorithmen werden hauptsächlich für die Datenintegrität verwendet.

Es folgt eine Liste empfohlener Algorithmen nach Anwendung:

Siehe auch