Sign in with Microsoft
Sign in or create an account.
Hello,
Select a different account.
You have multiple accounts
Choose the account you want to sign in with.

注意: 修訂 2023 年 6 月 22 日以更新解決方案和因應措施

注意: 修訂 2023 年 6 月 15 日以更新選項 4 和 5 的運作方式 

背景

在 2023 年 6 月 13 日,Microsoft 發佈了.NET Framework和 .NET 的安全性更新,這會影響執行時間匯入 X.509 憑證的方式。 這些變更可能會導致 X.509 憑證匯入會在更新之前匯入成功的情況下,傳回 CryptographicException。

這份檔說明受影響的應用程式所提供的變更和因應措施。

受影響的軟體

  • .NET Framework 2.0

  • .NET Framework 4.6.2、4.7、4.7.1、4.7.2

  • .NET Framework 4.8

  • .NET Framework 4.8.1

  • .NET 6.0

  • .NET 7.0

受影響的 API

變更描述

在 2023 年 6 月 13 日之前,若.NET Framework和 .NET 提供匯入的二進位憑證 blob,.NET Framework和 .NET 通常會將 blob 的驗證及匯入委派給基礎作業系統。 例如,在 Windows 上,.NET Framework和 .NET 通常會仰賴PFXImportCertStore API 進行驗證和匯入。

自 2023 年 6 月 13 起,變更當 .NET Framework 和 .NET 提供二進位憑證 blob 進行匯入時,.NET Framework和 .NET 在某些情況下會先執行額外的驗證,然後再將 blob 交給基礎作業系統。 此額外的驗證會執行一系列的語言檢查,以判斷傳入憑證在匯入時是否會惡意耗用資源。 由於這是超出基礎作業系統正常執行的 額外 驗證,因此可能會封鎖在 2023 年 6 月 13 日變更之前成功匯入的憑證 blob。

已知回歸

  1. 如果 X.509 憑證是使用不常高的密碼反覆運算計數匯出為 PFX blob,該憑證現在可能無法匯入。 大部分的憑證匯出機構會使用介於 2,000 - 10,000 之間的反覆運算計數。 套用安全性更新之後,包含超過 600,000 個反覆運算計數的憑證將無法匯入。

  2. 如果 X.509 憑證是使用Null密碼匯出 [例如,透過X509Certificate.Export(X509ContentType.Pfx, (string)null)或無密碼X509Certificate.Export(X509ContentType.Pfx)],該憑證現在可能無法匯入。
     

    附註: 上述回歸已在KB5028608中討論的 2023 年 6 月 22 日更新中解決。

  3. 如果 X.509 憑證已使用 Windows 保護 SID 專用金鑰的功能匯出為 PFX blob,該憑證現在可能無法匯入。 這會影響以下列方式建立的 PFX blob:

    • 透過 Windows 憑 證匯出精靈 ,並在精靈中指定應保護網域使用者的私人金鑰;或

    • 透過 PowerShell 的 Export-PfxCertificate Cmdlet,其中提供明確 -ProtectTo 引數;或

    • 透過提供明確 -protectto 引數的 certutil 公用程式;或

    • 透過提供PKCS12_PROTECT_TO_DOMAIN_SIDS標幟的 PFXExportCertStoreEx API。

解決&因應措施

各種因應措施存在,取決於您是否要在程式碼內的個別通話網站進行目標變更,或您想要變更單一應用程式的行為,或想要在全電腦上進行變更。

選項 1 (慣用) - 安裝更新的修補程式

附註: 這是慣用的選項,因為它會解決客戶經常回報的回歸問題,而且不需要對應用程式進行任何程式碼變更。

可複製性:此選項適用于所有版本的 .NET Framework 和 .NET。

此問題已在KB5028608中討論的 2023 年 6 月 22 日更新中解決。

Microsoft 建議遇到 2023 年 6 月 13 日發行版本導入回歸的客戶,在嘗試本文稍後列出的因應措施之前,先嘗試安裝此更新的修補程式。

選項 2 - 修改通話網站

可複製性:此選項適用于所有版本的 .NET Framework 和 .NET。

請考慮您匯入的 blob 是否值得信任。 例如,從信任的位置擷取的 blob 是由您控制下的資料庫或設定檔案,還是透過未經驗證或無權用戶端的網路要求提供?

Microsoft 極力建議您不要匯入未經驗證或沒有許可權的用戶端提供給您的 PFX blob,因為這些 BLOB 可能包含惡意資源耗盡行為。

如果您需要匯入不受信任方提供給您的公開金鑰憑證 blob,您可以使用下列程式碼安全地匯入這類 blob。 此範例程式碼使用GetCertContentType方法來判斷憑證 blob 的基礎類型,而且在您只預期匯入公開金鑰憑證 blob 的情況下,會拒絕 PFX blob。 當指定不受信任的非 PFX blob 時,X509Certificate2(byte[]) 建構器可以安全地使用。

using System.Security.Cryptography.X509Certificates;
public static X509Certificate2 ImportPublicCertificateBlob(byte[] blob)
{
     if (X509Certificate2.GetCertContentType(blob) == X509ContentType.Pfx)
    {
          throw new Exception("PFX blobs are disallowed.");
    }
   else
   {
         // Import only after we have confirmed it's not a PFX.
        return new X509Certificate2(blob);
    }
} 

如果您需要匯入無密碼的私密金鑰憑證 blob,而且您判斷該 blob 值得信任,您可以隱藏在 2023 年 6 月 13 日安全性發行之前執行的其他驗證檢查,方法是呼叫其他建構器負載過重。 例如,您可以稱建構器為負載過重,接受字串密碼引數,並傳遞 Null 做為引數值。 

byte[] blobToImport = GetBlobToImport(); // fetch this from a database, config, etc. 

// REGRESSION - byte[] ctor performs additional security checks X509Certificate2 certA = new X509Certificate2(blobToImport);

// RECOMMENDED WORKAROUND - different ctor overload suppresses additional security checks X509Certificate2 certB = new X509Certificate2(blobToImport, (string)null);

選項 3 - 使用環境變數來修改或隱藏額外的驗證

可複製性:此選項僅適用于所有版本的 .NET Framework。  不適用於 .NET 6.0+。

雖然.NET Framework預設限制匯入作業最多隻能執行 600,000 次的密碼反覆運算,但您可以使用環境變數,在全應用程式或全電腦上設定此限制。 這項新限制將適用于上述所有受影響 API 的叫用。

若要變更限制,請將環境變數COMPlus_Pkcs12UnspecifiedPasswordIterationLimit設定為新限制的值。 例如,若要將限制設為 1,000,000 (100 萬) 反覆運算,請設定環境變數,如下所示。

  • 此數位會控制 反覆運算限制,也就是 MAC 反覆運算計數、加密安全內容,以及串聯袋的反覆運算計數的總和。 如果您已使用明確反覆運算計數手動匯出 PFX <iter_count> (,例如,透過 openssl pkcs12 -export -iter <iter_count>) 並想要匯入 PFX blob,請將此環境變數設定為至少與所有預期反覆運算之總和一樣大的值。 實際上,.NET Framework和 .NET 可能會允許總反覆運算數稍微超過此處設定的任何明確限制。

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000

若要完全隱藏額外檢查,請將環境變數設定為特殊寄件值 -1,如下所示。

  • ⚠️ 警告:只有在您確定目標應用程式未處理不受信任的憑證輸入時,才將環境變數值設為 -1。

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1

選項 4 - 使用 AppCoNtext 修改或隱藏額外的驗證

可複製性:此選項僅適用于 .NET 6.0+。  不適用於 .NET Framework

雖然 .NET 預設限制匯入作業最多隻能執行 600,000 次的密碼反覆運算,但這個限制可以使用 AppCoNtext 參數在全應用程式中設定。 這項新限制將適用于上述所有受影響 API 的叫用。

若要變更限制,請將 AppCoNtext 參數 System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit 設為新限制的值。 例如,若要將限制設為 1,000,000 (100 萬) 反覆運算,請設定切換,如下所示。

  • 此數位會控制總反覆運算限制,也就是 MAC 反覆運算計數、加密安全內容,以及串聯袋的反覆運算計數的總和。 如果您已使用明確反覆運算計數手動匯出 PFX <iter_count> (,例如,透過 openssl pkcs12 -export -iter <iter_count>) 並想要匯入 PFX blob,請將此環境變數設定為至少與所有預期反覆運算之總和一樣大的值。 實際上,.NET 可能會允許總反覆運算數稍微超過此處設定的任何明確限制。

若要在應用程式的專案檔案中設定參數 (.csproj 或 .vbproj) :

<!--

  • This switch only works if the current project file represents an application. It has no effect if the current project file represents a shared library.

-->

<ItemGroup>

  • <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="1000000" />

</ItemGroup>

或者,您可以將名為 runtimeconfig.template.json 的檔案與下列內容放在包含您應用程式專案檔案的同一個目錄中:

{

     "configProperties": {

  • "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": 1000000

      }

}

如需有關變更 .NET 執行時間設定的詳細資訊,請參閱檔頁面.NET Runtime 設定

若要完全隱藏額外的檢查,請將設定參數設定為特殊寄件值 -1,如下所示。

⚠️ 警告:只有在您確定目標應用程式未處理不受信任的憑證輸入時,才將 AppCoNtext 切換為 -1。

在應用程式的專案檔案 (.csproj 或 .vbproj) :

<!--

  • This switch only works if the current project file represents an application. It has no effect if the current project file represents a shared library.

-->

<ItemGroup>

  • <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="-1" />

</ItemGroup>

或在 runtimeconfig.template.json 檔案中:

{

  • "configProperties": { 
  •     "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": -1

     }

}

選項 5 - 透過登錄 (僅限 Windows 的 .NET Framework) ,修改或隱藏整個電腦的其他驗證

可複製性:此選項僅適用于所有版本的 .NET Framework。  不適用於 .NET 6.0+。

雖然.NET Framework預設限制匯入作業最多隻能執行 600,000 次的密碼反覆運算,但您可以使用 HKLM 登錄在全電腦上設定此限制。 這項新限制將適用于上述所有受影響 API 的叫用。

若要變更限制,請在登錄機碼HKLM\Software\Microsoft\.NETFramework底下,將Pkcs12UnspecifiedPasswordIterationLimit值設為新的限制。 例如,若要將限制設為 1,000,000 (100 萬) 反覆運算,請從提升許可權的命令提示字元執行下列命令。

  • 此數位會控制 反覆運算限制,也就是 MAC 反覆運算計數、加密安全內容,以及串聯袋的反覆運算計數的總和。 如果您已使用明確反覆運算計數手動匯出 PFX <iter_count> (,例如,透過 openssl pkcs12 -export -iter <iter_count>) 並想要匯入該 PFX blob,請將此登錄值設為至少與所有預期反覆運算的總和一樣大的值。 實際上,.NET Framework可能會允許總反覆運算數稍微超過此處設定的任何明確限制。

  • 登錄設定是以架構為從屬參照。 若要確保應用程式無論其目標架構為何,都能觀察您的設定值,請記得同時修改 32 位和 64 位登錄,如下所示。

reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_DWORD /d 1000000 /reg:32
reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_DWORD /d 1000000 /reg:64

若要完全隱藏額外的檢查,請從提升許可權的命令提示字元將登錄值設為 -1,如下所示。

  • ⚠️ 警告:只有在您確定目的電腦上執行的服務未處理不受信任的憑證輸入時,才將登錄值設為 -1。

  • 若要設定 -1 寄件者,請使用REG_SZ類型,而非REG_DWORD類型。 登錄設定是以架構為從屬參照。 若要確保應用程式無論其目標架構為何,都能觀察您的設定值,請記得同時修改 32 位和 64 位登錄,如下所示。

reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_SZ /d -1 /reg:32
reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_SZ /d -1 /reg:64

若要還原登錄變更,請從提升許可權的命令提示字元刪除 Pkcs12UnspecifiedPasswordIterationLimit reg 值。

reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:32
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:64

Windows 特定筆記

在 Windows 上,.NET Framework透過 PFXImportCertStore 函數匯入憑證。 此函數會執行自己的驗證,包括對 PFX blob 的最大允許反覆運算計數設定自己的限制。 這些檢查仍會在 PFX 匯入時進行。 ..上述的 NET 特定環境變數和登錄機碼不會影響 PFXImportCertStore 執行這些檢查的情況。

Need more help?

Want more options?

探索訂閱權益、瀏覽訓練課程、瞭解如何保護您的裝置等等。

社群可協助您詢問並回答問題、提供意見反應,以及聆聽來自具有豐富知識的專家意見。

Was this information helpful?

How satisfied are you with the translation quality?
What affected your experience?
By pressing submit, your feedback will be used to improve Microsoft products and services. Your IT admin will be able to collect this data. Privacy Statement.

Thank you for your feedback!

×