KB5025823 Změna způsobu importu certifikátů X.509 aplikacemi .NET

Platí pro
.NET

Poznámka: Revidováno 22. června 2023 za účelem aktualizace řešení a alternativní řešení

Poznámka: Revidováno 15. června 2023 za účelem aktualizace řešení možností 4 a 5

Pozadí

13. června 2023 Microsoft vydal aktualizaci zabezpečení pro .NET Framework a .NET, která má vliv na způsob importu certifikátů X.509 modulem runtime. Tyto změny můžou způsobit, že import certifikátu X.509 vyvolá CryptographicException ve scénářích, kdy by import před aktualizací proběhl úspěšně.

Tento dokument popisuje změny a alternativní řešení, která jsou k dispozici pro ovlivněné aplikace.

Software obsahující tuto chybu

  • .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

Ovlivněná rozhraní API

Popis změny

Před změnou z 13. června 2023, kdy se .NET Framework a .NET zobrazí binární objekt blob certifikátu pro import, .NET Framework a .NET obvykle delegují ověření a import objektu blob na základní operační systém. Například ve Windows by rozhraní .NET Framework a .NET obvykle spoléhaly na rozhraní API PFXImportCertStore pro ověřování a import.

Od změny z 13. června 2023, kdy se .NET Framework a .NET zobrazí binární objekt blob certifikátu pro import, .NET Framework a .NET za určitých okolností provedou další ověření před předáním objektu blob podkladovému operačnímu systému. Toto dodatečné ověření provádí řadu heuristických kontrol, aby určilo, zda by příchozí certifikát nemohl při importu škodlivě vyčerpat zdroje. Vzhledem k tomu, že se jedná o další ověření nad rámec toho, co by základní operační systém normálně prováděl, může blokovat objekty blob certifikátu, které by se úspěšně importovaly před změnou 13. června 2023.

Známé regrese

  1. Pokud byl certifikát X.509 exportován jako objekt blob PFX s neobvykle vysokým počtem iterací hesla, může se stát, že tento certifikát nepůjde importovat. Většina exportních zařízení certifikátů používá počet iterací někde mezi 2 000 a 10 000. Po instalaci aktualizace zabezpečení se nezdaří import certifikátů obsahujících počet iterací vyšší než 600 000.

  2. Pokud byl certifikát X.509 exportován s použitím nulového hesla [například via X509Certificate.Export(X509ContentType.Pfx, (string)null) nebo bez X509Certificate.Export(X509ContentType.Pfx)]hesla, může se nyní stát, že tento certifikát nepůjde importovat.
     

    Poznámka

    Výše uvedená regrese byla řešena v aktualizaci z 22. června 2023, která je popsána v KB5028608.

  3. Pokud byl certifikát X.509 exportován jako objekt blob PFX pomocí funkce Windows chránit privátní klíč na SID, může se nyní stát, že import tohoto certifikátu selže. To bude mít vliv na objekty blob PFX vytvořené následujícím způsobem:

    • Prostřednictvím Průvodce exportem certifikátu systému Windows a zadáním v průvodci, že soukromý klíč by měl být chráněn pro uživatele domény; nebo
    • Prostřednictvím rutiny PowerShellu Export-PfxCertificate s explicitním -ProtectTo argumentem; nebo
    • Prostřednictvím nástroje certutil , kde je zadán explicitní -protectto argument; nebo
    • Prostřednictvím rozhraní API PFXExportCertStoreEx , kde je k dispozici příznak PKCS12_PROTECT_TO_DOMAIN_SIDS.

Řešení & alternativní řešení

Existují různá alternativní řešení v závislosti na tom, zda chcete provádět cílené změny v jednotlivých webech volání v rámci kódu, nebo chcete změnit chování jedné aplikace, nebo chcete provádět změny v celém počítači.

Možnost 1 (upřednostňována) – Nainstalujte aktualizovanou opravu

Poznámka

Toto je upřednostňovaná možnost, protože řeší běžně hlášené regrese zákazníků a nevyžaduje žádné změny kódu v aplikaci.

Použitelnost: Tato možnost platí pro všechny verze .NET Framework a .NET.

Tento problém byl vyřešen v aktualizaci z 22. června 2023, která je popsána v KB5028608.

Společnost Microsoft doporučuje, aby zákazníci, u kterých dochází k regresím způsobeným vydáním z 13. června 2023, vyzkoušeli instalaci této aktualizované opravy, než se pokusí o alternativní řešení uvedená dále v tomto dokumentu.

Možnost 2 – Úprava webu volání

Použitelnost: Tato možnost platí pro všechny verze .NET Framework a .NET.

Zvažte, jestli je importovaný objekt blob důvěryhodný. Byl například objekt blob načten z důvěryhodného umístění, jako je databáze nebo konfigurační soubor pod vaší kontrolou, nebo byl poskytnut prostřednictvím síťového požadavku od neověřeného nebo neprivilegovaného klienta?

Společnost Microsoft důrazně doporučuje neimportovat objekty blob PFX, které vám poskytnou neověření nebo neprivilegovaní klienti, protože tyto objekty blob můžou obsahovat škodlivé chování při vyčerpání prostředků.

Pokud potřebujete importovat objekt blob certifikátu veřejného klíče , který vám poskytla nedůvěryhodná strana, můžete k bezpečnému importu takového objektu blob použít následující kód. Tento ukázkový kód používá metodu GetCertContentType k určení, jaký je podkladový typ objektu blob certifikátu, a odmítá objekty blob PFX v případech, kdy očekáváte pouze import objektu blob certifikátu veřejného klíče. Konstruktor X509Certificate2(byte[]) je bezpečný pro použití, pokud jsou mu poskytnuty nedůvěryhodné objekty blob bez PFX.


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);
    }
} 

Pokud potřebujete importovat objekt blob certifikátu privátního klíče bez hesla a zjistili jste, že objekt blob je důvěryhodný, můžete potlačit další ověřovací kontroly provedené vydáním zabezpečení z 13. června 2023 voláním jiného přetížení konstruktoru. Můžete například volat přetížení konstruktoru, které přijímá řetězcový argument hesla a předá hodnotu null jako hodnotu argumentu.

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);

Možnost 3 – Úprava nebo potlačení dodatečného ověřování pomocí proměnné prostředí

Použitelnost: Tato možnost platí pouze pro všechny verze rozhraní .NET Framework.  Nevztahuje se na rozhraní .NET 6.0+.

I když .NET Framework ve výchozím nastavení omezuje operace importu tak, aby netrvalo více než 600 000 iterací hesla, tento limit je možné nakonfigurovat na základě celé aplikace nebo počítače pomocí proměnné prostředí. Toto nové omezení se bude vztahovat na všechna volání výše uvedených dotčených rozhraní API.

Pokud chcete limit změnit, nastavte proměnnou COMPlus_Pkcs12UnspecifiedPasswordIterationLimit prostředí na hodnotu, která by měla být novým limitem. Pokud chcete například nastavit limit na 1 000 000 (jeden milion) iterací, nastavte proměnnou prostředí, jak je znázorněno níže.

  • Toto číslo řídí celkový limit iterací, což je součet počtu iterací MAC, šifrovaného bezpečného obsahu a počtu iterací zahaleného sáčku. Pokud jste ručně exportovali PFX pomocí explicitního počtu <iterací iter_count> (například přes openssl pkcs12 -export -iter <iter_count>) a chcete tento objekt blob PFX importovat, nastavte tuto proměnnou prostředí na hodnotu alespoň tak velkou, jako je součet všech očekávaných iterací. V praxi můžou .NET Framework a .NET umožnit, aby celkový počet iterací mírně překročil jakýkoli zde nakonfigurovaný explicitní limit.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000

Chcete-li zcela potlačit další kontroly, nastavte proměnnou prostředí na speciální hodnotu sentinel -1, jak je znázorněno níže.

  • ⚠️ Upozornění: Hodnotu proměnné prostředí nastavte na hodnotu -1 pouze v případě, že jste si jisti, že cílová aplikace nezpracovává vstup nedůvěryhodného certifikátu.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1

Možnost 4 – Úprava nebo potlačení dalšího ověřování pomocí AppContext

Použitelnost: Tato možnost platí jenom pro .NET 6.0+.  Nevztahuje se na .NET Framework

I když rozhraní .NET ve výchozím nastavení omezuje operace importu tak, aby netrvalo více než 600 000 iterací hesla, je možné tento limit nakonfigurovat pro celou aplikaci pomocí přepínače AppContext. Toto nové omezení se bude vztahovat na všechna volání výše uvedených dotčených rozhraní API.

Pokud chcete limit změnit, nastavte přepínač AppContext System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit na hodnotu, jaký by měl být nový limit. Pokud chcete například nastavit limit na 1 000 000 (jeden milion) iterací, nastavte přepínač, jak je znázorněno níže.

  • Toto číslo řídí celkový limit iterací, což je součet počtu iterací MAC, šifrovaného bezpečného obsahu a počtu iterací zahaleného sáčku. Pokud jste ručně exportovali PFX pomocí explicitního počtu <iterací iter_count> (například přes openssl pkcs12 -export -iter <iter_count>) a chcete tento objekt blob PFX importovat, nastavte tuto proměnnou prostředí na hodnotu alespoň tak velkou, jako je součet všech očekávaných iterací. V praxi může rozhraní .NET umožnit, aby celkový počet iterací mírně překročil jakýkoli explicitní limit, který je zde nakonfigurovaný.

Nastavení přepínače v souboru projektu aplikace (.csproj nebo .vbproj):

<!--

  • Tento přepínač funguje jenom v případě, že aktuální soubor projektu představuje aplikaci. Pokud aktuální soubor projektu představuje sdílenou knihovnu, nemá tento krok žádný vliv.

-->

<ItemGroup>

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

</ItemGroup>

Případně můžete do stejného adresáře, který obsahuje soubor projektu vaší aplikace, umístit soubor s názvem runtimeconfig.template.json s následujícím obsahem:

{

     "configProperties": {

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

      }

}

Další informace o změně nastavení konfigurace modulu runtime .NET najdete na stránce dokumentace Nastavení konfigurace modulu runtime .NET.

Chcete-li zcela potlačit další kontroly, nastavte konfigurační přepínač na speciální hodnotu sentinelu -1, jak je znázorněno níže.

⚠️ Upozornění: Přepínač AppContext nastavte na hodnotu -1 pouze v případě, že jste si jisti, že cílová aplikace nezpracovává vstup nedůvěryhodných certifikátů.

V souboru projektu aplikace (.csproj nebo .vbproj):

<!--

  • Tento přepínač funguje jenom v případě, že aktuální soubor projektu představuje aplikaci. Pokud aktuální soubor projektu představuje sdílenou knihovnu, nemá tento krok žádný vliv.

-->

<ItemGroup>

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

</ItemGroup>

Nebo v souboru runtimeconfig.template.json:

{

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

     }

}

Možnost 5 – Úprava nebo potlačení dodatečného ověřování v celém počítači prostřednictvím registru (jenom Windows pro .NET Framework)

Použitelnost: Tato možnost platí pouze pro všechny verze rozhraní .NET Framework.  Nevztahuje se na rozhraní .NET 6.0+.

I když .NET Framework ve výchozím nastavení omezuje operace importu tak, aby nemohly trvat více než 600 000 iterací hesla, tento limit je možné nakonfigurovat pro celý počítač pomocí registru HKLM. Toto nové omezení se bude vztahovat na všechna volání výše uvedených dotčených rozhraní API.

Pokud chcete limit změnit, nastavte v klíči HKLM\Software\Microsoft\.NETFrameworkregistru hodnotu Pkcs12UnspecifiedPasswordIterationLimit , na kterou by měl být nový limit. Pokud chcete například nastavit limit na 1 000 000 (jeden milion) iterací, spusťte níže uvedené příkazy z příkazového řádku se zvýšenými oprávněními.

  • Toto číslo řídí celkový limit iterací, což je součet počtu iterací MAC, šifrovaného bezpečného obsahu a počtu iterací zahaleného sáčku. Pokud jste PFX ručně exportovali pomocí explicitního počtu <iterací iter_count> (například přes openssl pkcs12 -export -iter <iter_count>) a chcete tento objekt blob PFX importovat, nastavte tuto hodnotu registru alespoň na hodnotu, která odpovídá součtu všech očekávaných iterací. V praxi může rozhraní .NET Framework umožnit, aby celkový počet iterací mírně překročil jakýkoli zde nakonfigurovaný explicitní limit.
  • Nastavení registru závisí na architektuře. Pokud chcete zajistit, aby aplikace sledovaly nakonfigurovanou hodnotu bez ohledu na jejich cílovou architekturu, nezapomeňte upravit 32bitový i 64bitový registr, jak je uvedeno níže.

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

Chcete-li tyto dodatečné kontroly zcela potlačit, nastavte hodnotu registru na hodnotu -1 z příkazového řádku se zvýšenými oprávněními, jak je znázorněno níže.

  • ⚠️ Upozornění: Hodnotu registru nastavte na hodnotu -1 jenom v případě, že jste si jistí, že služby spuštěné na cílovém počítači nezpracovávají vstup nedůvěryhodných certifikátů.
  • Chcete-li nastavit sentinel -1, použijte typ REG_SZ místo typu REG_DWORD. Nastavení registru závisí na architektuře. Pokud chcete zajistit, aby aplikace sledovaly nakonfigurovanou hodnotu bez ohledu na jejich cílovou architekturu, nezapomeňte upravit 32bitový i 64bitový registr, jak je uvedeno níže.

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

Pokud chcete vrátit změny registru, odstraňte hodnotu registru Pkcs12UnspecifiedPasswordIterationLimit z příkazového řádku se zvýšenými oprávněními.

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

Poznámky specifické pro Windows

Ve Windows .NET Framework importuje certifikáty prostřednictvím funkce PFXImportCertStore. Tato funkce provádí vlastní ověření, včetně stanovení vlastních limitů maximálního povoleného počtu iterací objektu blob PFX. Tyto kontroly budou při importu PFX stále probíhat. Společnost . Proměnné prostředí specifické pro síť a klíče registru popsané výše nemají vliv na to, jak PFXImportCertStore tyto kontroly provádí.