KB5025823 Promjena načina uvoza certifikata X.509

Primjenjuje se na
.NET

Napomena: Revidirano 22. lipnja 2023. radi ažuriranja razlučivosti i zaobilaznih rješenja

Napomena: Revidirano 15. lipnja 2023. radi ažuriranja zaobilaznog rješenja mogućnosti 4 i 5

Osnovne informacije

Microsoft je 13. lipnja 2023. objavio sigurnosno ažuriranje za .NET Framework i .NET koje utječe na način na koji runtime uvozi certifikate X.509. Te promjene mogu uzrokovati da uvoz certifikata X.509 generira CryptographicException u scenarijima u kojima bi uvoz uspio prije ažuriranja.

U ovom su dokumentu opisane promjene i zaobilazna rješenja dostupna za zahvaćene aplikacije.

Softver na koji se to odnosi

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

Zahvaćeni API-ji

Opis promjene

Prije promjene od 13. lipnja 2023., kada se .NET Framework i .NET predstavi blob binarnog certifikata za uvoz, .NET Framework i .NET obično bi delegirali provjeru valjanosti i uvoz blob-a temeljnom operacijskom sustavu. Na primjer, u sustavu Windows .NET Framework i .NET obično se oslanjaju na API PFXImportCertStore za provjeru valjanosti i uvoz.

Od promjene od 13. lipnja 2023., kada se za .NET Framework i .NET predoči blob binarnog certifikata za uvoz, .NET Framework i .NET u nekim će okolnostima provesti dodatnu provjeru valjanosti prije predaje bloba temeljnom operacijskom sustavu. Tom se dodatnom provjerom provjerava niz heurističkih provjera da bi se utvrdilo je li dolazni certifikat zlonamjerno iscrpio resurse prilikom uvoza. Budući da je ovo dodatna provjera valjanosti izvan onoga što bi temeljni OS inače izvodio, možda blokira blobove certifikata koji bi se uspješno uvezli prije promjene 13. lipnja 2023.

Poznate regresije

  1. Ako je certifikat X.509 izvezen kao blob PFX-a pomoću neuobičajeno velikog broja iteracija lozinki, uvoz tog certifikata sada možda neće uspjeti. Većina objekata za izvoz certifikata koristi broj iteracija između 2000 i 10 000. Nakon primjene sigurnosnog ažuriranja uvoz neće uspjeti za certifikate koji sadrže broj iteracija veći od 600 000.

  2. Ako je certifikat X.509 izvezen pomoću lozinke bez vrijednosti null [npr. putem X509Certificate.Export(X509ContentType.Pfx, (string)null) ili bez X509Certificate.Export(X509ContentType.Pfx)]lozinke , uvoz tog certifikata sada možda neće uspjeti.
     

    Napomena

    Gornja regresija riješena je u ažuriranju od 22. lipnja 2023. o kojem se raspravljalo u KB5028608.

  3. Ako je certifikat X.509 izvezen kao blob PFX-a pomoću mogućnosti sustava Windows da zaštiti privatni ključ SID-a, uvoz tog certifikata možda neće uspjeti. To će utjecati na PFX blobove stvorene na sljedeće načine:

    • putem čarobnjaka za izvoz certifikata sustava Windows i navođenje u čarobnjaku da privatni ključ treba biti zaštićen za korisnika domene; ili
    • Putem PowerShellova cmdleta Export-PfxCertificate u kojem je naveden eksplicitni -ProtectTo argument; ili
    • Putem uslužnog programa certutil gdje je naveden eksplicitni -protectto argument; ili
    • Putem API-ja PFXExportCertStoreEx na kojem se navodi PKCS12_PROTECT_TO_DOMAIN_SIDS zastavica.

Rješenje & zaobilazna rješenja

Postoje različita zaobilazna rješenja, ovisno o tome želite li napraviti ciljane promjene na pojedinačnim mjestima za pozive u kodu, ili želite promijeniti ponašanje pojedinačne aplikacije ili želite unijeti promjene na razini računala.

1. mogućnost (preferirano) – instalacija ažurirane zakrpe

Napomena

Ovo je preferirana mogućnost jer rješava najčešće prijavljene regresije klijenata i ne zahtijeva mijenjanje koda aplikacije.

Primjenjivost: Ta se mogućnost odnosi na sve verzije .NET Framework i .NET.

Taj je problem riješen u ažuriranju od 22. lipnja 2023. o kojem se govori u KB5028608.

Microsoft korisnicima koji imaju regresije uvedene izdavanjem od 13. lipnja 2023. preporučuje da pokušaju instalirati ovu ažuriranu zakrpu prije nego što isprobaju zaobilazna rješenja navedena u nastavku ovog dokumenta.

2. mogućnost – izmjena web-mjesta poziva

Primjenjivost: Ta se mogućnost odnosi na sve verzije .NET Framework i .NET.

Razmislite je li blob koji uvozite vjerodostojan. Na primjer, je li blob dohvaćen s pouzdanog mjesta, kao što je baza podataka ili konfiguracijska datoteka pod vašom kontrolom, ili je pak isporučen putem mrežnog zahtjeva klijenta čiji autentičnost nije provjeren ili nije imao ovlasti?

Microsoft vam svakako preporučuje da ne uvozite PFX blobove koje su vam dali klijenti čija autentičnost nije provjerena ili ih nisu ovlastili jer bi ti blobovi mogli sadržavati zlonamjerna ponašanja pri iscrpljivanju resursa.

Ako morate uvesti blob certifikata javnog ključa koji vam je dala nepouzdana strana, takav blob možete sigurno uvesti pomoću koda u nastavku. Ovaj ogledni kod koristi metodu GetCertContentType da bi odredio temeljnu vrstu bloba certifikata i odbacuje blobove PFX-a u slučajevima kada očekujete samo uvoz blob certifikata javnog ključa. Sastavljač X509Certificate2(byte[]) je siguran za korištenje kada se daju nepouzdani blobovi koji nisu 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);
    }
} 

Ako morate uvesti blob certifikata privatnog ključa bez lozinki i utvrdili ste da je blob pouzdan, dodatne provjere provjere valjanosti provedene do sigurnosnog izdanja od 13. lipnja 2023. možete potisnuti pozivanjem drugog preopterećenja graditelja. Možete, primjerice, nazvati konstruktor preopterećenjem koji prihvaća niz argumenta lozinke i proslijediti null za vrijednost argumenta.

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. mogućnost – izmjena ili onemogućivanje dodatne provjere valjanosti pomoću varijable okruženja

Primjenjivost: Ta se mogućnost odnosi samo na sve verzije .NET Framework.  Ne odnosi se na .NET 6.0+.

Iako .NET Framework prema zadanim postavkama ograničava operacije uvoza na najviše 600 000 iteracija lozinke, to se ograničenje može konfigurirati na razini aplikacije ili računala pomoću varijable okruženja. To novo ograničenje primjenjivat će se na sva gore navedena pozivanja zahvaćenih API-ja.

Da biste promijenili ograničenje, postavite varijablu COMPlus_Pkcs12UnspecifiedPasswordIterationLimit okruženja na vrijednost novog ograničenja. Da biste, primjerice, postavili ograničenje na 1 000 000 (milijun) iteracija, postavite varijablu okruženja kao što je prikazano u nastavku.

  • Taj broj kontrolira ukupno ograničenje iteracija, koje je zbroj broja iteracija MAC-a, šifriranog sigurnog sadržaja i broja iteracija zakrivljene vrećice. Ako ste ručno izvezli PFX pomoću eksplicitnog iter_count> broja <iteracija (npr. putem openssl pkcs12 -export -iter <iter_count>) i želite uvesti taj PFX blob, postavite varijablu okruženja na vrijednost barem onoliko velika koliko je zbroj svih očekivanih iteracija. U praksi .NET Framework i .NET mogu dopustiti da ukupan broj iteracija malo premaši bilo koje ovdje konfigurirano eksplicitno ograničenje.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000

Da biste u potpunosti onemogućili dodatne provjere, postavite varijablu okruženja na vrijednost posebnog pregledavatelja -1, kao što je prikazano u nastavku.

  • ️ Upozorenje: vrijednost varijable okruženja postavite na -1 samo ako ste sigurni da ciljna aplikacija ne obrađuje unos nepouzdanog certifikata.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1

4. mogućnost – izmjena ili onemogućivanje dodatne provjere valjanosti pomoću značajke AppContext

Primjenjivost: Ta se mogućnost odnosi samo na .NET 6.0+.  Ne odnosi se na .NET Framework

Iako .NET prema zadanim postavkama ograničava operacije uvoza na najviše 600 000 iteracija lozinke, to se ograničenje može konfigurirati u cijeloj aplikaciji pomoću parametra AppContext. To novo ograničenje primjenjivat će se na sva gore navedena pozivanja zahvaćenih API-ja.

Da biste promijenili ograničenje, postavite prekidač AppContext System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit na vrijednost nove granice. Na primjer, da biste postavili ograničenje na 1 000 000 (milijun) iteracija, postavite prekidač kao što je prikazano u nastavku.

  • Taj broj kontrolira ukupno ograničenje iteracija, koje je zbroj broja iteracija MAC-a, šifriranog sigurnog sadržaja i broja iteracija zakrivljene vrećice. Ako ste ručno izvezli PFX pomoću eksplicitnog iter_count> broja <iteracija (npr. putem openssl pkcs12 -export -iter <iter_count>) i želite uvesti taj PFX blob, postavite varijablu okruženja na vrijednost barem onoliko velika koliko je zbroj svih očekivanih iteracija. U praksi .NET može dopustiti da ukupan broj iteracija malo premaši bilo koje ovdje konfigurirano ograničenje.

Da biste postavili prekidač unutar datoteke projekta aplikacije (.csproj ili .vbproj):

<!--

  • Taj prekidač funkcionira samo ako trenutna datoteka projekta predstavlja aplikaciju. Nema učinka ako trenutna datoteka projekta predstavlja zajedničku biblioteku.

-->

<ItemGroup>

  • <RuntimeHostConfigurationOption include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" value="1000000" />

</ItemGroup>

Možete i staviti datoteku naziva runtimeconfig.template.json sa sljedećim sadržajem u direktorij u kojem se nalazi projektna datoteka vaše aplikacije:

{

     "configProperties": {

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

      }

}

Dodatne informacije o promjeni konfiguracijskih postavki izvođenja platforme .NET potražite na stranici dokumentacije u postavkama konfiguracije izvođenja platforme .NET.

Da biste u potpunosti onemogućili dodatne provjere, postavite konfiguracijski prekidač na vrijednost posebnog upravitelja -1, kao što je prikazano u nastavku.

️ Upozorenje: prekidač AppContext postavite na -1 samo ako ste sigurni da ciljna aplikacija ne obrađuje unos nepouzdanog certifikata.

U datoteci projekta aplikacije (.csproj ili .vbproj):

<!--

  • Taj prekidač funkcionira samo ako trenutna datoteka projekta predstavlja aplikaciju. Nema učinka ako trenutna datoteka projekta predstavlja zajedničku biblioteku.

-->

<ItemGroup>

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

</ItemGroup>

Ili unutar runtimeconfig.template.json datoteke:

{

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

     }

}

5. mogućnost – izmjena ili onemogućivanje dodatne provjere valjanosti na računalu putem registra (samo Windows za .NET Framework)

Primjenjivost: Ta se mogućnost odnosi samo na sve verzije .NET Framework.  Ne odnosi se na .NET 6.0+.

Iako .NET Framework prema zadanim postavkama ograničava operacije uvoza na najviše 600 000 iteracija lozinke, to se ograničenje može konfigurirati na svim uređajima pomoću registra HKLM. To novo ograničenje primjenjivat će se na sva gore navedena pozivanja zahvaćenih API-ja.

Da biste promijenili ograničenje, u odjeljku ključa HKLM\Software\Microsoft\.NETFrameworkregistra postavite vrijednost na novu vrijednost Pkcs12UnspecifiedPasswordIterationLimit . Da biste, primjerice, postavili ograničenje na 1 000 000 (milijun) iteracija, pokrenite naredbe kao što je prikazano u nastavku iz privilegiranog naredbenog retka.

  • Taj broj kontrolira ukupno ograničenje iteracija, koje je zbroj broja iteracija MAC-a, šifriranog sigurnog sadržaja i broja iteracija zakrivljene vrećice. Ako ste ručno izvezli PFX pomoću eksplicitnog iter_count> broja <iteracija (npr. putem openssl pkcs12 -export -iter <iter_count>) i želite uvesti taj PFX blob, postavite tu vrijednost registra na vrijednost koja je barem jednako velika kao zbroj svih očekivanih iteracija. .NET Framework u praksi može dopustiti da ukupan broj iteracija malo premaši bilo koje ovdje konfigurirano eksplicitno ograničenje.
  • Postavka registra ovisi o arhitekturi. Da biste bili sigurni da aplikacije poštuju konfiguriranu vrijednost neovisno o ciljnoj arhitekturi, ne zaboravite izmijeniti i 32-bitni i 64-bitni registar, kao što je prikazano u nastavku.

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

Da biste u potpunosti poništili dodatne provjere, postavite vrijednost registra na -1 iz privilegiranog naredbenog retka, kao što je prikazano u nastavku.

  • ⚠️ Upozorenje: vrijednost registra postavite na -1 samo ako ste sigurni da servisi koji se pokreću na ciljnom računalu ne obrađuju unos nepouzdanog certifikata.
  • Da biste postavili sentinel -1, koristite vrstu REG_SZ umjesto REG_DWORD vrste. Postavka registra ovisi o arhitekturi. Da biste bili sigurni da aplikacije poštuju konfiguriranu vrijednost neovisno o ciljnoj arhitekturi, ne zaboravite izmijeniti i 32-bitni i 64-bitni registar, kao što je prikazano u nastavku.

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

Da biste poništili promjene registra, izbrišite vrijednost registra Pkcs12UnspecifiedPasswordIterationLimit iz povišenog naredbenog retka.

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

Napomene specifične za Windows

U sustavu Windows .NET Framework uvozi certifikate putem funkcije PFXImportCertStore. Ova funkcija provodi vlastitu provjeru valjanosti, uključujući postavljanje vlastitih ograničenja na najveći dopušteni broj iteracija PBX bloba. Te će se provjere i dalje provoditi nakon uvoza PFX-a. Polje . Gore opisane varijable okruženja i ključevi registra specifični za NET ne utječu na to kako PFXImportCertStore provodi te provjere.