分享方式:


.NET 密碼編譯模型

.NET 提供許多標準密碼編譯演算法的實作。

物件繼承

.NET 密碼編譯系統會實作可擴充的衍生類別繼承模式。 階層如下所述:

這種衍生類別模式可讓您加入新的演算法或現有演算法的新實作。 例如,若要建立新的公開金鑰演算法,您會繼承自 AsymmetricAlgorithm 類別。 若要建立特定演算法的新實作,您會建立該演算法的非抽象衍生類別。

接下來,此繼承模型不會用於 AesGcmShake128 等新類型的基本類型。 這些演算法為 sealed。 如果您需要這些類型的擴充性模式或抽象概念,抽象概念的實作是開發人員的責任。

單次 API

從 .NET 5 開始,已針對雜湊和 HMAC 引進更簡易的 API。 雖然稍微較不具彈性,但下列單次 API:

  • 更易於使用 (且較不容易誤用)
  • 減少配置或無配置
  • 安全執行緒
  • 使用適用於平台的最佳可用實作

雜湊和 HMAC 基本類型會透過型別上的靜態 HashData 方法公開單次 API,例如 SHA256.HashData。 靜態 API 不提供內建擴充性機制。 如果您要實作自己的演算法,建議您也提供演算法的類似靜態 API。

RandomNumberGenerator 類別也提供靜態方法,以使用密碼編譯隨機資料建立或填滿緩衝區。 這些方法一律會使用系統的密碼編譯安全虛擬隨機數產生器 (CSPRNG)。

.NET 中的演算法實作方式

做為可供演算法使用的不同實作方式範例,請考慮對稱演算法。 所有對稱演算法的基底都是 SymmetricAlgorithm,由 AesTripleDES 和其他不再建議的項目所繼承。

Aes 是由 AesCryptoServiceProviderAesCngAesManaged 所繼承。

在 Windows 上的 .NET Framework:

  • *CryptoServiceProvider 演算法類別 (例如 AesCryptoServiceProvider) 是在演算法之 WINDOWS 密碼編譯 API (CAPI) 實作周圍的包裝函式。
  • *Cng 演算法類別 (例如 ECDiffieHellmanCng) 是在 WINDOWS 新一代密碼編譯 (CNG) 實作周圍的包裝函式。
  • *Managed 類別 (例如 AesManaged) 完全以 Managed 程式碼撰寫。 不過,*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

選擇演算法

您選取演算法時可能有不同的原因:例如,為了資料完整性、為了資料隱私權,或是為了產生金鑰。 對稱和雜湊演算法是要用來出於完整性的原因 (防止變更) 或隱私權的原因 (防止檢視) 保護資料。 雜湊演算法主要用於資料完整性。

以下是依應用程式的建議演算法清單:

另請參閱