.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:
Klass för algoritmtyp, till exempel SymmetricAlgorithm, AsymmetricAlgorithmeller HashAlgorithm. Den här nivån är abstrakt.
Algoritmklass som ärver från en algoritmtypklass, Aestill exempel , RSA, eller ECDiffieHellman. Den här nivån är abstrakt.
Implementering av en algoritmklass som ärver från en algoritmklass, AesManagedtill exempel , RC2CryptoServiceProvidereller ECDiffieHellmanCng. Den här nivån är helt implementerad.
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
, *Managed
och *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:
- Datasekretess:
- Dataintegritet:
- Digital signatur:
- Nyckelutbyte:
- Slumptalsgenerering:
- Generera en nyckel från ett lösenord: