Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
.NET offre implementazioni di molti algoritmi di crittografia standard.
Ereditarietà degli oggetti
Il sistema di crittografia .NET implementa un modello estendibile di ereditarietà della classe derivata. La gerarchia è la seguente:
Classe di tipo algoritmo, ad esempio SymmetricAlgorithm, AsymmetricAlgorithmo HashAlgorithm. Questo livello è astratto.
Classe di algoritmo che eredita da una classe di tipo algoritmo come, ad esempio, Aes, RSA o ECDiffieHellman. Questo livello è astratto.
Implementazione di una classe di algoritmo che eredita da una classe di algoritmi, ad esempio , AesManagedRC2CryptoServiceProvidero ECDiffieHellmanCng. Questo livello è completamente implementato.
Questo modello di classi derivate consente di aggiungere un nuovo algoritmo o una nuova implementazione di un algoritmo esistente. Ad esempio, per creare un nuovo algoritmo a chiave pubblica, si eredita dalla AsymmetricAlgorithm classe . Per creare una nuova implementazione di un algoritmo specifico, creare una classe derivata non astratta di tale algoritmo.
In futuro, questo modello di ereditarietà non viene usato per nuovi tipi di primitive come AesGcm o Shake128. Questi algoritmi sono sealed
. Se è necessario un modello di estendibilità o un'astrazione su questi tipi, l'implementazione dell'astrazione è responsabilità dello sviluppatore.
API singola operazione
A partire da .NET 5, sono state introdotte API più semplici per l'hashing e HMAC. Anche se leggermente meno flessibili, queste API a colpo singolo:
- Sono più facili da usare (e meno soggetti a uso improprio)
- Ridurre le allocazioni o essere liberi da allocazioni
- Sono thread-safe
- Usare l'implementazione migliore disponibile per la piattaforma
Le primitive hash e HMAC espongono un'API one-shot tramite un metodo statico HashData
sul tipo, ad esempio SHA256.HashData. Le API statiche non offrono alcun meccanismo di estendibilità predefinito. Se si implementano algoritmi personalizzati, è consigliabile offrire anche API statiche simili dell'algoritmo.
La RandomNumberGenerator classe offre anche metodi statici per creare o riempire buffer con dati casuali crittografici. Questi metodi usano sempre il generatore di numeri pseudocasualmente sicuri del sistema (CSPRNG).
Modalità di implementazione degli algoritmi in .NET
Come esempio delle diverse implementazioni disponibili per un algoritmo, prendere in considerazione algoritmi simmetrici. La base per tutti gli algoritmi simmetrici è SymmetricAlgorithm, ereditata da Aes, TripleDESe altre non più consigliate.
Aes viene ereditato da AesCryptoServiceProvider, AesCnge AesManaged.
In .NET Framework on Windows:
-
*CryptoServiceProvider
le classi di algoritmi, ad esempio AesCryptoServiceProvider, utilizzano l'API crittografica di Windows (CAPI) per un algoritmo. -
*Cng
le classi di algoritmi, ad esempio ECDiffieHellmanCng, sono wrapper per l'implementazione CNG (Cryptography Next Generation) di Windows. -
*Managed
le classi, ad esempio AesManaged, vengono scritte interamente nel codice gestito.*Managed
le implementazioni non sono certificate dagli standard FIPS (Federal Information Processing Standards) e possono essere più lente rispetto alle*CryptoServiceProvider
classi wrapper e*Cng
.
In .NET Core e .NET 5 e versioni successive, tutte le classi di implementazione (*CryptoServiceProvider
, *Managed
e *Cng
) sono wrapper per gli algoritmi del sistema operativo. Se gli algoritmi del sistema operativo sono certificati FIPS, .NET usa algoritmi certificati FIPS. Per altre informazioni, vedere Crittografia multipiattaforma.
Nella maggior parte dei casi, non è necessario fare riferimento direttamente a una classe di implementazione dell'algoritmo, ad esempio AesCryptoServiceProvider
. I metodi e le proprietà necessari in genere si trovano nella classe dell'algoritmo di base, ad esempio Aes
. Creare un'istanza di una classe di implementazione predefinita usando un metodo factory nella classe dell'algoritmo di base e fare riferimento alla classe dell'algoritmo di base. Ad esempio, vedere la riga di codice evidenziata nell'esempio seguente:
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
Scegliere un algoritmo
È possibile selezionare un algoritmo per diversi motivi, ad esempio per l'integrità dei dati, per la privacy dei dati o per generare una chiave. Gli algoritmi simmetrici e hash sono destinati alla protezione dei dati per motivi di integrità (protezione dalle modifiche) o per motivi di privacy (protezione dalla visualizzazione). Gli algoritmi hash vengono usati principalmente per l'integrità dei dati.
Di seguito è riportato un elenco di algoritmi consigliati per applicazione:
- Privacy dei dati:
- Integrità dei dati:
- Firma digitale:
- Scambio di chiavi:
- Generazione di numeri casuali:
- Generazione di una chiave da una password: