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:
Klasa typów algorytmów, taka jak SymmetricAlgorithm, AsymmetricAlgorithmlub HashAlgorithm. Ten poziom jest abstrakcyjny.
Klasa algorytmu dziedziczona z klasy typu algorytmu, na przykład Aes, RSAlub ECDiffieHellman. Ten poziom jest abstrakcyjny.
Implementacja klasy algorytmu dziedziczonej z klasy algorytmu, na przykład AesManaged, RC2CryptoServiceProviderlub ECDiffieHellmanCng. Ten poziom jest w pełni zaimplementowany.
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:
- Prywatność danych:
- Integralność danych:
- Podpis cyfrowy:
- Wymiana kluczy:
- Generowanie liczb losowych:
- Generowanie klucza na podstawie hasła: