Dela via


.NET-kryptografimodell

.NET tillhandahåller implementeringar av många vanliga kryptografiska algoritmer.

Objektarv

Kryptografisystemet .NET implementerar ett utökningsbart mönster för arv av härledda klasser. Hierarkin är följande:

Med det här mönstret med härledda klasser kan du lägga till en ny algoritm eller en ny implementering av en befintlig algoritm. Om du till exempel vill skapa en ny algoritm för offentlig nyckel ärver du från AsymmetricAlgorithm klassen. Om du vill skapa en ny implementering av en specifik algoritm skapar du en icke-abstrakt härledd klass för den algoritmen.

Framöver används inte den här arvsmodellen för nya typer av primitiver som AesGcm eller Shake128. Dessa algoritmer är sealed. Om du behöver ett utökningsmönster eller abstraktion över dessa typer är implementeringen av abstraktionen utvecklarens ansvar.

Api:er med ett skott

Från och med .NET 5 introducerades enklare API:er för hashing och HMAC. Dessa api:er med ett skott är något mindre flexibla:

  • Är lättare att använda (och mindre benägna att missbrukas)
  • Minska allokeringar eller är allokeringsfria
  • Är trådsäkra
  • Använd den bästa tillgängliga implementeringen för plattformen

Hashing- och HMAC-primitiverna exponerar ett api med ett skott via en statisk HashData metod för typen, till exempel SHA256.HashData. De statiska API:erna erbjuder ingen inbyggd utökningsmekanism. Om du implementerar dina egna algoritmer rekommenderar vi att du även erbjuder liknande statiska API:er för algoritmen.

Klassen RandomNumberGenerator erbjuder också statiska metoder för att skapa eller fylla buffertar med kryptografiska slumpmässiga data. Dessa metoder använder alltid systemets kryptografiskt säkra pseudorandomnummergenerator (CSPRNG).

Hur algoritmer implementeras i .NET

Som ett exempel på de olika implementeringar som är tillgängliga för en algoritm bör du överväga symmetriska algoritmer. Basen för alla symmetriska algoritmer är SymmetricAlgorithm, som ärvs av Aes, TripleDESoch andra som inte längre rekommenderas.

Aes ärvs av AesCryptoServiceProvider, AesCngoch AesManaged.

I .NET Framework i Windows:

  • *CryptoServiceProvider algoritmklasser, till exempel AesCryptoServiceProvider, är omsluter implementeringen av en algoritm i Windows Cryptography API (CAPI).
  • *Cng algoritmklasser, till exempel ECDiffieHellmanCng, är omslutna kring CNG-implementeringen (Windows Cryptography Next Generation).
  • *Managed Klasser, till exempel AesManaged, skrivs helt i hanterad kod. *Managed implementeringar certifieras inte av FIPS (Federal Information Processing Standards) och kan vara långsammare än *CryptoServiceProvider omslutningsklasserna och *Cng .

I .NET Core- och .NET 5- och senare versioner är alla implementeringsklasser (*CryptoServiceProvider, *Managedoch *Cng) omslutningar för operativsystemalgoritmerna (OS). Om operativsystemets algoritmer är FIPS-certifierade använder .NET FIPS-certifierade algoritmer. Mer information finns i Plattformsoberoende kryptografi.

I de flesta fall behöver du inte direkt referera till en algoritmimplementeringsklass, till exempel AesCryptoServiceProvider. De metoder och egenskaper som du vanligtvis behöver finns i basalgoritmklassen, till exempel Aes. Skapa en instans av en standardimplementeringsklass med hjälp av en fabriksmetod i basalgoritmklassen och referera till basalgoritmklassen. Se till exempel den markerade kodraden i följande exempel:

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

Välj en algoritm

Du kan välja en algoritm av olika skäl: till exempel för dataintegritet, för datasekretess eller för att generera en nyckel. Symmetriska algoritmer och hash-algoritmer är avsedda att skydda data av antingen integritetsskäl (skydda mot ändringar) eller sekretessskäl (skydda mot visning). Hash-algoritmer används främst för dataintegritet.

Här är en lista över rekommenderade algoritmer per program:

Se även