Model kryptografii platformy .NET

Platforma .NET udostępnia implementacje wielu standardowych algorytmów kryptograficznych.

Dziedziczenie obiektów

System kryptografii .NET implementuje rozszerzalny wzorzec dziedziczenia klasy pochodnej. Hierarchia jest następująca:

Ten wzorzec klas pochodnych umożliwia dodanie nowego algorytmu lub nowej implementacji istniejącego algorytmu. Na przykład w celu utworzenia nowego algorytmu klucza publicznego należy dziedziczyć z AsymmetricAlgorithm klasy. Aby utworzyć nową implementację określonego algorytmu, należy utworzyć nie abstrakcyjną klasę pochodną tego algorytmu.

W przyszłości ten model dziedziczenia nie jest używany dla nowych rodzajów typów pierwotnych, takich jak AesGcm lub Shake128. Te algorytmy to sealed. Jeśli potrzebujesz wzorca rozszerzalności lub abstrakcji dla tych typów, implementacja abstrakcji jest obowiązkiem dewelopera.

Interfejsy API jednorazowe

Począwszy od platformy .NET 5, prostsze interfejsy API zostały wprowadzone do tworzenia skrótów i HMAC. Chociaż nieco mniej elastyczne, te jednoskrętowe interfejsy API:

  • Są łatwiejsze do użycia (i mniej podatne na niewłaściwe użycie)
  • Zmniejszanie alokacji lub wolne od alokacji
  • Czy wątki są bezpieczne
  • Korzystanie z najlepszej dostępnej implementacji dla platformy

Skróty i elementy pierwotne HMAC uwidaczniają jednorazowy interfejs API za pomocą metody statycznej HashData w typie, takim jak SHA256.HashData. Statyczne interfejsy API nie oferują wbudowanego mechanizmu rozszerzalności. Jeśli implementujesz własne algorytmy, zaleca się również oferowanie podobnych statycznych interfejsów API algorytmu.

Klasa RandomNumberGenerator oferuje również metody statyczne tworzenia lub wypełniania buforów przy użyciu kryptograficznych danych losowych. Te metody zawsze używają kryptograficznie bezpiecznego generatora pseudorandomów systemu (CSPRNG).

Jak algorytmy są implementowane na platformie .NET

Jako przykład różnych implementacji dostępnych dla algorytmu rozważ algorytmy symetryczne. Podstawą dla wszystkich algorytmów symetrycznych jest SymmetricAlgorithm, który jest dziedziczony przez Aes, TripleDESi inne, które nie są już zalecane.

Aes jest dziedziczony przez AesCryptoServiceProvider, AesCngi AesManaged.

W programie .NET Framework w systemie Windows:

  • *CryptoServiceProvider klasy algorytmów, takie jak AesCryptoServiceProvider, są otokami implementacji algorytmu interfejsu API kryptografii systemu Windows (CAPI).
  • *Cng klasy algorytmów, takie jak ECDiffieHellmanCng, są otokami implementacji następnej generacji (CNG) kryptografii systemu Windows.
  • *Managed klasy, takie jak AesManaged, są zapisywane w całości w kodzie zarządzanym. *Managed implementacje nie są certyfikowane przez Federal Information Processing Standards (FIPS) i mogą być wolniejsze niż *CryptoServiceProvider klasy otoki i *Cng .

W wersjach .NET Core i .NET 5 i nowszych wszystkie klasy implementacji (*CryptoServiceProvider, *Managed, i *Cng) są otokami algorytmów systemu operacyjnego. Jeśli algorytmy systemu operacyjnego mają certyfikat FIPS, platforma .NET używa algorytmów certyfikowanych ze standardem FIPS. Aby uzyskać więcej informacji, zobacz Kryptografia międzyplatformowa.

W większości przypadków nie trzeba bezpośrednio odwoływać się do klasy implementacji algorytmu, takiej jak AesCryptoServiceProvider. Metody i właściwości, których zwykle potrzebujesz, znajdują się w klasie algorytmu podstawowego, takiej jak Aes. Utwórz wystąpienie domyślnej klasy implementacji przy użyciu metody fabryki w klasie algorytmu podstawowego i zapoznaj się z klasą algorytmu podstawowego. Zobacz na przykład wyróżniony wiersz kodu w poniższym przykładzie:

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

Wybieranie algorytmu

Możesz wybrać algorytm z różnych powodów: na przykład integralność danych, prywatność danych lub wygenerowanie klucza. Algorytmy symetryczne i algorytmy skrótu są przeznaczone do ochrony danych ze względów integralności (ochrona przed zmianą) lub prywatnością (ochrona przed wyświetlaniem). Algorytmy skrótu są używane głównie na potrzeby integralności danych.

Oto lista zalecanych algorytmów według aplikacji:

Zobacz też