.NET-cryptografiemodel

.NET biedt implementaties van veel standaard cryptografische algoritmen.

Objectovername

Het .NET-cryptografiesysteem implementeert een uitbreidbaar patroon van overname van afgeleide klassen. De hiërarchie is als volgt:

Met dit patroon van afgeleide klassen kunt u een nieuw algoritme of een nieuwe implementatie van een bestaand algoritme toevoegen. Als u bijvoorbeeld een nieuw algoritme voor een openbare sleutel wilt maken, neemt u deze over van de AsymmetricAlgorithm klasse. Als u een nieuwe implementatie van een specifiek algoritme wilt maken, maakt u een niet-abstracte afgeleide klasse van dat algoritme.

In de toekomst wordt dit overnamemodel niet gebruikt voor nieuwe soorten primitieven zoals AesGcm of Shake128. Deze algoritmen zijn sealed. Als u een uitbreidbaarheidspatroon of abstractie voor deze typen nodig hebt, is de implementatie van de abstractie de verantwoordelijkheid van de ontwikkelaar.

Api's met één opname

Vanaf .NET 5 zijn eenvoudigere API's geïntroduceerd voor hashing en HMAC. Hoewel dit iets minder flexibel is, zijn deze API's met één opname :

  • Zijn gemakkelijker te gebruiken (en minder gevoelig voor misbruik)
  • Toewijzingen verminderen of toewijzingsvrij zijn
  • Zijn thread veilig
  • Gebruik de best beschikbare implementatie voor het platform

De hashing- en HMAC-primitieven maken een api met één opname beschikbaar via een statische HashData methode voor het type, zoals SHA256.HashData. De statische API's bieden geen ingebouwd uitbreidbaarheidsmechanisme. Als u uw eigen algoritmen implementeert, is het raadzaam om ook vergelijkbare statische API's van het algoritme te bieden.

De RandomNumberGenerator klasse biedt ook statische methoden voor het maken of vullen van buffers met cryptografische willekeurige gegevens. Deze methoden gebruiken altijd de cryptografisch beveiligde pseudorandom-nummergenerator (CSPRNG) van het systeem.

Hoe algoritmen worden geïmplementeerd in .NET

Als voorbeeld van de verschillende implementaties die beschikbaar zijn voor een algoritme, kunt u symmetrische algoritmen overwegen. De basis voor alle symmetrische algoritmen is SymmetricAlgorithm, die wordt overgenomen door Aes, TripleDESen andere die niet meer worden aanbevolen.

Aes wordt overgenomen door AesCryptoServiceProvider, AesCngen AesManaged.

In .NET Framework on Windows:

  • *CryptoServiceProvider algoritmenklassen, zoals AesCryptoServiceProvider, zijn wrappers rond de CAPI-implementatie (Windows Cryptography API) van een algoritme.
  • *Cng algoritmenklassen, zoals ECDiffieHellmanCng, zijn wrappers rond de implementatie van Windows Cryptography Next Generation (CNG).
  • *Managed klassen, zoals AesManaged, worden volledig geschreven in beheerde code. *Managed implementaties worden niet gecertificeerd door de Federal Information Processing Standards (FIPS) en kunnen langzamer zijn dan de *CryptoServiceProvider en *Cng wrapperklassen.

In .NET Core en .NET 5 en hoger zijn alle implementatieklassen (*CryptoServiceProvider, *Manageden *Cng) wrappers voor de algoritmen van het besturingssysteem .NET Core en .NET 5 en hoger. Als de algoritmen van het besturingssysteem FIPS-gecertificeerd zijn, gebruikt .NET fips-gecertificeerde algoritmen. Zie Platformoverschrijdende cryptografie voor meer informatie.

In de meeste gevallen hoeft u niet rechtstreeks te verwijzen naar een implementatieklasse voor het algoritme, zoals AesCryptoServiceProvider. De methoden en eigenschappen die u doorgaans nodig hebt, zijn gebaseerd op de basisalgoritmenklasse, zoals Aes. Maak een exemplaar van een standaard implementatieklasse met behulp van een factory-methode op de basisalgoritmenklasse en raadpleeg de basisalgoritmenklasse. Zie bijvoorbeeld de gemarkeerde coderegel in het volgende voorbeeld:

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

Een algoritme kiezen

U kunt om verschillende redenen een algoritme selecteren: bijvoorbeeld voor gegevensintegriteit, gegevensprivacy of om een sleutel te genereren. Symmetrische en hash-algoritmen zijn bedoeld voor het beveiligen van gegevens om integriteitsredenen (beschermen tegen wijziging) of privacyredenen (bescherming tegen weergave). Hash-algoritmen worden voornamelijk gebruikt voor gegevensintegriteit.

Hier volgt een lijst met aanbevolen algoritmen per toepassing:

Zie ook