Share via


不支援將密碼編譯抽象概念的預設實作具現化

從 .NET 5.0 開始,密碼編譯抽象概念上的無參數 Create() 多載已淘汰,並會引發警告。

變更描述

在 .NET Framework 2.0 - 4.8 中,可以設定 HashAlgorithm.Create() 等抽象密碼編譯基本 Factory,以傳回不同的演算法。 例如,在 .NET Framework 4.8 的預設安裝 上,無參數靜態方法 HashAlgorithm.Create() 會傳回 SHA1 演算法的執行個體,如下列程式碼片段所示。

僅限 .NET Framework

// Return an instance of the default hash algorithm (SHA1).
HashAlgorithm alg = HashAlgorithm.Create();
// Prints 'System.Security.Cryptography.SHA1CryptoServiceProvider'.
Console.WriteLine(alg.GetType());

// Change the default algorithm to be SHA256, not SHA1.
CryptoConfig.AddAlgorithm(typeof(SHA256CryptoServiceProvider), typeof(HashAlgorithm).FullName);
alg = HashAlgorithm.Create();
// Prints 'System.Security.Cryptography.SHA256CryptoServiceProvider'.
Console.WriteLine(alg.GetType());

您也可以使用全機器組態來變更預設演算法,而不需要以程式設計方式呼叫 CryptoConfig

在 .NET Core 2.0 - 3.1 中,HashAlgorithm.Create() 等抽象密碼編譯基本 Factory 一律擲回 PlatformNotSupportedException

// Throws PlatformNotSupportedException on .NET Core.
HashAlgorithm alg = HashAlgorithm.Create();

在 .NET 5 和更新版本中,HashAlgorithm.Create() 等抽象密碼編譯基本 Factory 已標示為已淘汰,並產生識別碼為 SYSLIB0007 的編譯時間警告。 在執行階段,這些方法會繼續擲回 PlatformNotSupportedException

// Throws PlatformNotSupportedException.
// Also produces compile-time warning SYSLIB0007 on .NET 5+.
HashAlgorithm alg = HashAlgorithm.Create();

此變更僅限編譯時期。 舊版 .NET Core 沒有執行階段變更。

注意

  • 只有 Create() 方法的無參數多載已淘汰。 參數化多載未淘汰,仍如預期運作。

    // Call Create(string), providing an explicit algorithm family name.
    // Works in .NET Framework, .NET Core, and .NET 5+.
    HashAlgorithm hashAlg = HashAlgorithm.Create("SHA256");
    
  • 「特定」演算法系列的無參數多載 (非抽象概念) 未過時,會繼續如預期運作。

    // Call a specific algorithm family's parameterless Create() ctor.
    // Works in .NET Framework, .NET Core, and .NET 5+.
    Aes aesAlg = Aes.Create();
    

變更原因

.NET Framework 中的密碼編譯組態系統,不再存在於 .NET Core 和 .NET 5+ 中,因為舊版系統不允許適度的加密彈性。 .NET 的回溯相容性需求也使得架構無法更新特定密碼編譯 API,以跟上密碼編譯的演進。 例如,在 SHA-1 雜湊演算法是先進技術的時期,.NET Framework 1.0 中引進了 HashAlgorithm.Create() 方法。 經過二十年,現在 SHA-1 已不敷使用,但我們無法將 HashAlgorithm.Create() 變更為傳回不同的演算法。 這麼做會在取用的應用程式中造成無法接受的中斷性變更。

最佳做法要求取用密碼編譯基本類型的程式庫 (例如 AES、SHA-* 和 RSA) 應完全控制其取用這些基本類型的方式。 需要未來校訂的應用程式,應利用較高層級的程式庫來包裝這些基本類型,並加入金鑰管理和密碼編譯功能。 這些程式庫通常是由裝載環境提供。 其中一個範例是 ASP.NET 的資料保護程式庫,可代表呼叫的應用程式處理這些疑慮。

導入的版本

5.0

  • 建議的動作是,以特定演算法的 Factory 方法呼叫,取代已淘汰 API 的呼叫,例如 Aes.Create()。 這可讓您完全控制要具現化的演算法。

  • 如果您需要與使用已淘汰 API 之 .NET Framework 應用程式所產生的現有承載保持相容,請使用下表中建議的取代項目。 表格提供從 .NET Framework 預設演算法到其 .NET 5+ 對等項目的對應。

    .NET Framework .NET Core / .NET 5+ 相容的取代項目 備註
    AsymmetricAlgorithm.Create() RSA.Create()
    HashAlgorithm.Create() SHA1.Create() SHA-1 演算法已被視為無效。 如果可行,請考慮使用更強大的演算法。 如需進一步指導,請洽詢安全顧問。
    HMAC.Create() HMACSHA1() 對於大部分的新式應用程式,都不建議使用 HMACSHA1 演算法。 如果可行,請考慮使用更強大的演算法。 如需進一步指導,請洽詢安全顧問。
    KeyedHashAlgorithm.Create() HMACSHA1() 對於大部分的新式應用程式,都不建議使用 HMACSHA1 演算法。 如果可行,請考慮使用更強大的演算法。 如需進一步指導,請洽詢安全顧問。
    SymmetricAlgorithm.Create() Aes.Create()
  • 如果您必須繼續呼叫已淘汰的無參數 Create() 多載,可以在程式碼中隱藏 SYSLIB0007 警告。

    #pragma warning disable SYSLIB0007 // Disable the warning.
    HashAlgorithm alg = HashAlgorithm.Create(); // Still throws PNSE.
    #pragma warning restore SYSLIB0007 // Re-enable the warning.
    

    您也可以在專案檔中隱藏警告。 這麼做會停用專案中所有來源檔案的警告。

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
       <TargetFramework>net5.0</TargetFramework>
       <!-- NoWarn below suppresses SYSLIB0007 project-wide -->
       <NoWarn>$(NoWarn);SYSLIB0007</NoWarn>
      </PropertyGroup>
    </Project>
    

    注意

    隱藏 SYSLIB0007 只會停用此處所列密碼編譯 API 的淘汰警告, 而不會停用其他任何警告。 此外,即使您隱藏警告,這些已淘汰的 API 仍會在執行階段擲回 PlatformNotSupportedException

受影響的 API