.NET 提供許多標準密碼編譯演算法的實作。
物件繼承
.NET 密碼編譯系統會實作衍生類別繼承的可延伸模式。 階層如下所示:
演算法類型類別,例如 SymmetricAlgorithm、AsymmetricAlgorithm 或 HashAlgorithm。 這個層級是抽象的。
繼承自算法類型的演算法類別,例如 Aes、 RSA 或 ECDiffieHellman。 這個層級是抽象的。
繼承自演算法類別的演算法類別實現,例如 AesManaged、RC2CryptoServiceProvider或 ECDiffieHellmanCng。 此層級已完全實作。
這種衍生類別模式可讓您新增演算法或現有演算法的新實作。 例如,若要建立新的公鑰演算法,您會繼承自 AsymmetricAlgorithm 類別。 若要建立特定演算法的新實作,您會建立該演算法的非抽象衍生類別。
今後,這種繼承模型將不再用於新的基本類型,如AesGcm或Shake128。 這些演算法為 sealed
。 如果您需要這些類型的擴充性模式或抽象概念,抽象概念的實作是開發人員的責任。
單次 API
從 .NET 5 開始,已針對哈希和 HMAC 引進更簡單的 API。 雖然稍微較不具彈性,但下列 單次 API:
- 更容易使用(且不易誤用)
- 減少資源分配或不需配置
- 線程是否安全
- 使用平臺的最佳可用實作
哈希和 HMAC 基本類型會透過型別上的靜態 HashData
方法公開一次性 API,例如 SHA256.HashData。 靜態 API 不提供內建擴充性機制。 如果您要實作自己的演算法,建議您也提供演算法的類似靜態 API。
類別 RandomNumberGenerator 也提供靜態方法,以使用密碼編譯隨機數據建立或填滿緩衝區。 這些方法一律使用系統的密碼編譯安全虛擬隨機數產生器 (CSPRNG)。
在 .NET 中實作演算法的方式
作為演算法可用之不同實作的範例,請考慮對稱演算法。 所有對稱演算法的基底為 SymmetricAlgorithm,由 Aes、TripleDES 和其他不再建議的演算法所繼承。
Aes 由 AesCryptoServiceProvider、 AesCng和 AesManaged繼承。
在 Windows 上的 .NET Framework 中:
-
*CryptoServiceProvider
演算法類別,例如 AesCryptoServiceProvider,是對 Windows 密碼編譯 API (CAPI) 演算法實作的封裝器。 -
*Cng
演算法類別,例如 ECDiffieHellmanCng,是 Windows 密碼編譯新一代 (CNG) 實作的包裝函式。 -
*Managed
類別,例如 AesManaged,完全以受控程式碼撰寫。*Managed
實作未經過聯邦資訊處理標準(FIPS)的認證,而且可能比*CryptoServiceProvider
和*Cng
包裝函式類別慢。
在 .NET Core 和 .NET 5 及後續版本中,所有實作類別(*CryptoServiceProvider
、*Managed
和 *Cng
)都是作業系統 (OS) 演算法的包裝函式。 如果 OS 演算法經過 FIPS 認證,則 .NET 會使用經過 FIPS 認證的演算法。 如需詳細資訊,請參閱 跨平臺密碼編譯。
在大部分情況下,您不需要直接參考演算法實作類別,例如 AesCryptoServiceProvider
。 您通常需要的方法與屬性位於基底演演算法類別上, 例如 Aes
。 在基底演算法類別上使用 Factory 方法建立預設實作類別的實例,並參考基底演算法類別。 例如,請參閱下列範例中反白顯示的程式代碼行:
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
選擇演算法
您可以基於不同原因選取演算法:例如,數據完整性、數據隱私權或產生密鑰。 對稱和哈希演算法的目的是為了保護數據,原因包括完整性原因(保護不變更)或隱私權原因(防止檢視)。 哈希演算法主要用於數據完整性。
以下是依應用程式建議的演算法清單:
- 數據隱私權:
- 資料完整性:
- 數位簽章:
- 金鑰交換:
- 隨機數字產生:
- 從密碼產生金鑰: