Huomautus: Tarkistettu 22. kesäkuuta 2023 ratkaisun ja vaihtoehtoisten menetelmien päivittämiseksi
Huomautus: Päivitetty 15. kesäkuuta 2023 vaihtoehtojen 4 ja 5 päivittämiseksi
Taustaa
Microsoft julkaisi 13. kesäkuuta 2023 .NET Framework- ja .NET -suojauspäivityksen, joka vaikuttaa siihen, miten Runtime tuo X.509-varmenteita. Nämä muutokset voivat aiheuttaa sen, että X.509-varmenteen tuonti aiheuttaa CryptographicException-virheen skenaarioissa, joissa tuonti olisi onnistunut ennen päivitystä.
Tässä asiakirjassa kuvataan muutos ja käytettävissä olevat vaihtoehtoiset menetelmät sovelluksille, joihin tämä vaikuttaa.
Ohjelmistot, joita ongelma koskee
- .NET Framework 2.0
- .NET Framework 4.6.2, 4.7, 4.7.1 ja 4.7.2
- .NET Framework 4.8
- .NET Framework 4.8.1
- .NET 6.0
- .NET 7.0
Ohjelmointirajapinnat, joihin tämä vaikuttaa
- new X509Certificate(byte[])
- X509Certificate.Import(tavu[])
- new X509Certificate2(byte[])
- X509Certificate2.Import(byte[])
- X509Certificate2Collection.Import(byte[])
Muutoksen kuvaus
Ennen 13. kesäkuuta 2023 muutosta, kun .NET Framework ja .NET esitetään binaarivarmenteen blob-objekti tuontia varten, .NET Framework ja .NET yleensä delegoivät blob-objektin vahvistuksen ja tuonnin pohjana olevaan käyttöjärjestelmään. Esimerkiksi Windowsissa .NET Framework ja .NET käyttävät yleensä PFXImportCertStore-ohjelmointirajapintaa vahvistamiseen ja tuontiin.
13. kesäkuuta 2023 alkaen .NET Framework ja .NET esittävät binaarivarmenteen blob-objektin tuontia varten, ja .NET Framework ja .NET suorittavat joissakin tilanteissa lisävahvistuksen ennen blob-objektin luovuttamista pohjana olevalle käyttöjärjestelmälle. Tämä lisätarkistus suorittaa sarjan heuristisia tarkistuksia sen määrittämiseksi, kuluttaisiko saapuva varmenne haitallisesti resurssit tuotaessa. Koska tämä on lisävahvistus verrattuna siihen, mitä pohjana oleva käyttöjärjestelmä normaalisti suorittaisi, se voi estää varmenteen blob-objektit, jotka olisi tuotu onnistuneesti ennen 13. kesäkuuta 2023 tehtyä muutosta.
Tunnetut regressiot
Jos X.509-varmenne on viety PFX-blob-objektina käyttämällä epätavallisen suurta salasanan iteraatiomäärää, varmenteen tuonti voi nyt epäonnistua. Useimmat varmenteiden vientilaitokset käyttävät iteraatiomäärää välillä 2 000–10 000. Kun suojauspäivitys on otettu käyttöön, tuonti epäonnistuu varmenteille, joiden iteraatiomäärä on suurempi kuin 600 000.
Jos X.509-varmenne on viety käyttämällä tyhjäarvoista salasanaa [esim. kautta
X509Certificate.Export(X509ContentType.Pfx, (string)null)tai salasanattomanaX509Certificate.Export(X509ContentType.Pfx)], varmenteen tuonti voi nyt epäonnistua.
Huomautus
Edellä mainittu regressio on korjattu 22. kesäkuuta 2023 -päivityksessä, jota käsiteltiin KB5028608.
Jos X.509-varmenne on viety PFX-blob-objektina käyttämällä Windowsin kykyä suojata SID-tunnuksen yksityinen avain, varmenteen tuonti voi nyt epäonnistua. Tämä vaikuttaa seuraavilla tavoilla luotuihin PFX-blob-objekteihin:
- Windowsin ohjatun varmenteiden vientitoiminnon kautta ja määrittämällä ohjatussa toiminnossa, että yksityinen avain tulee suojata toimialueen käyttäjältä; tai
- PowerShellin Export-PfxCertificate-cmdlet-komennon kautta, jossa annetaan eksplisiittinen
-ProtectToargumentti; tai -
certutil-apuohjelman kautta, jossa annetaan eksplisiittinen
-protecttoargumentti; tai - PFXExportCertStoreEx-ohjelmointirajapinnan kautta, jossa PKCS12_PROTECT_TO_DOMAIN_SIDS-merkintä annetaan.
Ratkaisu & vaihtoehtoiset menetelmät
On olemassa erilaisia vaihtoehtoisia menetelmiä sen mukaan, haluatko tehdä kohdennettuja muutoksia koodin yksittäisiin soittosivustoihin, muuttaa yksittäisen sovelluksen toimintaa tai tehdä koko konetta koskevia muutoksia.
Vaihtoehto 1 (suositeltava) – Asenna päivitetty korjaustiedosto
Huomautus
Tämä on suositeltava vaihtoehto, koska se käsittelee yleisesti raportoituja asiakkaiden regressioita eikä edellytä koodimuutoksia sovellukseen.
Soveltuvuus: Tämä asetus koskee kaikkia .NET Framework- ja .NET-versioita.
Tämä ongelma on ratkaistu 22. kesäkuuta 2023 -päivityksessä, jota käsiteltiin KB5028608.
Microsoft suosittelee, että asiakkaat, jotka kokevat 13. kesäkuuta 2023 -julkaisun mukanaan tuomia regressioita, yrittävät asentaa tämän päivitetyn korjaustiedoston ennen myöhemmin tässä asiakirjassa lueteltujen vaihtoehtoisten menetelmien kokeilemista.
Vaihtoehto 2 – Puhelusivuston muokkaaminen
Soveltuvuus: Tämä asetus koskee kaikkia .NET Framework- ja .NET-versioita.
Mieti, onko tuotava blob-objekti luotettava. Haettiinko blob-objekti esimerkiksi luotetusta sijainnista, kuten hallinnassasi olevasta tietokannasta tai määritystiedostosta, vai toimitettiinko se todentamattoman tai käyttöoikeudettoman asiakkaan tekemän verkkopyynnön kautta?
Microsoft suosittelee vahvasti, että et tuo PFX-blob-objekteja, jotka olet saanut todentamattomilta tai käyttöoikeudettomilta asiakkailta, koska nämä blob-objektit voivat sisältää haitallisia resurssien loppumiseen liittyviä toimintoja.
Jos haluat tuoda ei-luotetun osapuolen sinulle antaman julkisen avaimen varmenteen blob-objektin, voit tuoda tällaisen blob-objektin turvallisesti seuraavan koodin avulla. Tämä mallikoodi käyttää GetCertContentType-menetelmää varmenteen blob-objektin pohjana olevan tyypin määrittämiseen ja hylkää PFX-blob-objektit tapauksissa, joissa oletetaan tuotavasi vain julkisen avaimen varmenteen blob-objektia. Konstruktori X509Certificate2(byte[]) on turvallinen käyttää, kun sille annetaan ei-luotettuja ei-PFX-blob-objekteja.
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);
}
}
Jos sinun on tuotava salasanattoman yksityisen avaimen varmenteen blob-objekti ja olet määrittänyt, että blob-objekti on luotettava, voit estää 13. kesäkuuta 2023 julkaistun suojausjulkaisun suorittamat muut vahvistustarkistukset kutsumalla toista konstruktorin ylikuormitusta. Voit esimerkiksi kutsua konstruktoria ylikuormitukseksi, joka hyväksyy merkkijonon salasanaargumentin ja antaa argumentin arvoksi nollan.
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);
Vaihtoehto 3 – Lisävahvistuksen muokkaaminen tai poistaminen ympäristömuuttujan avulla
Soveltuvuus: Tämä asetus koskee vain kaikkia .NET Framework -versioita. Se ei koske .NET 6.0+:aa.
Vaikka .NET Framework rajoittaa oletusarvoisesti salasanan tuontitoiminnot enintään 600 000 iteraatioon, tämä rajoitus voidaan määrittää sovellus- tai konekohtaisesti ympäristömuuttujan avulla. Tämä uusi raja koskee kaikkia edellä mainittujen ohjelmointirajapintojen kutsuja.
Voit muuttaa rajoitusta asettamalla ympäristömuuttujalle COMPlus_Pkcs12UnspecifiedPasswordIterationLimit uuden rajoituksen arvon. Jos haluat esimerkiksi asettaa rajaksi 1 000 000 (miljoona) iteraatiota, määritä ympäristömuuttuja alla esitetyllä tavalla.
- Tämä luku määrittää iteraatioiden kokonaisrajan , joka on MAC-iteraatiomäärän, salatun kassakaapin sisällön ja suojellun pussin iteraatiomäärän summa. Jos olet vienyt PFX:n manuaalisesti käyttämällä eksplisiittistä iteraatiomäärän <iter_count> (esimerkiksi openssl pkcs12 -export -iter <iter_count)> -kautta ja haluat tuoda kyseisen PFX-blob-objektin, määritä tämän ympäristömuuttujan arvo, joka on vähintään yhtä suuri kuin kaikkien odotettujen iteraatiokertojen summa. Käytännössä .NET Framework ja .NET voivat sallia iteraatioiden kokonaismäärän ylittää hieman tässä määritetyn rajoituksen.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000
Jos haluat estää lisätarkistukset kokonaan, aseta ympäristömuuttuja erityiseen vartija-arvoon -1 alla esitetyllä tavalla.
- ⚠️ Varoitus: Aseta ympäristömuuttujan arvoksi -1 vain, jos olet varma, että kohdesovellus ei käsittele epäluotettavia varmennesyötteitä.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1
Vaihtoehto 4 – Lisävahvistuksen muokkaaminen tai poistaminen AppContextin avulla
Soveltuvuus: Tämä vaihtoehto koskee vain .NET 6.0+:aa. Se ei koske .NET Framework
Vaikka .NET rajoittaa oletusarvoisesti tuontitoiminnot enintään 600 000 salasanan iteraatioon, tämä rajoitus voidaan määrittää koko sovelluksessa AppContext-kytkimellä. Tämä uusi raja koskee kaikkia edellä mainittujen ohjelmointirajapintojen kutsuja.
Jos haluat muuttaa rajoitusta, määritä AppContext-valitsin System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit uuden rajoituksen arvoksi. Jos haluat esimerkiksi asettaa rajaksi 1 000 000 (miljoona) iteraatiota, määritä valitsin alla kuvatulla tavalla.
- Tämä luku määrittää iteraatioiden kokonaisrajan, joka on MAC-iteraatiomäärän, salatun kassakaapin sisällön ja suojellun pussin iteraatiomäärän summa. Jos olet vienyt PFX:n manuaalisesti käyttämällä eksplisiittistä iteraatiomäärän <iter_count> (esimerkiksi openssl pkcs12 -export -iter <iter_count)> -kautta ja haluat tuoda kyseisen PFX-blob-objektin, määritä tämän ympäristömuuttujan arvo, joka on vähintään yhtä suuri kuin kaikkien odotettujen iteraatiokertojen summa. Käytännössä .NET voi sallia iteraatioiden kokonaismäärän ylittää hieman tässä määritetyn rajoituksen.
Voit määrittää valitsimen sovelluksen projektitiedostossa (.csproj tai .vbproj) seuraavasti:
<!--
- Valitsin toimii vain, jos nykyinen projektitiedosto edustaa sovellusta. Sillä, edustaako nykyinen projektitiedosto jaettua kirjastoa, ei ole vaikutusta.
-->
<ItemGroup>
- <RuntimeHostConfigurationOption include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" value="1000000" />
</ItemGroup>
Vaihtoehtoisesti voit sijoittaa tiedoston nimeltä runtimeconfig.template.json seuraavalla sisällöllä samaan hakemistoon, joka sisältää sovelluksesi projektitiedoston:
{
"configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": 1000000
}
}
Lisätietoja suorituksenaikaisten .NET -määritysasetusten muuttamisesta on ohjesivulla .NET Runtime -määritysasetukset.
Jos haluat estää lisätarkistukset kokonaan, aseta määrityskytkin erityiseen vartija-arvoon -1 alla olevan kuvan mukaisesti.
⚠️ Varoitus: Aseta AppContext-valitsin arvoon -1 vain, jos olet varma, että kohdesovellus ei käsittele epäluotettavaa varmennesyötettä.
Sovelluksen projektitiedostossa (.csproj tai .vbproj):
<!--
- Valitsin toimii vain, jos nykyinen projektitiedosto edustaa sovellusta. Sillä, edustaako nykyinen projektitiedosto jaettua kirjastoa, ei ole vaikutusta.
-->
<ItemGroup>
- <RuntimeHostConfigurationOption include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" value="-1" />
</ItemGroup>
Tai runtimeconfig.template.json tiedostossa:
{
- "configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": -1
}
}
Vaihtoehto 5 – Koneen laajuisen lisävahvistuksen muokkaaminen tai poistaminen rekisterin kautta (vain Windows-versio .NET Framework:lle)
Soveltuvuus: Tämä asetus koskee vain kaikkia .NET Framework -versioita. Se ei koske .NET 6.0+:aa.
Vaikka .NET Framework rajoittaa oletusarvoisesti tuontitoiminnot enintään 600 000 salasanan iteraatioon, tämä rajoitus voidaan määrittää koko koneessa HKLM-rekisterin avulla. Tämä uusi raja koskee kaikkia edellä mainittujen ohjelmointirajapintojen kutsuja.
Jos haluat muuttaa rajoitusta, määritä rekisteriavaimen HKLM\Software\Microsoft\.NETFrameworkkohdalla arvoksi Pkcs12UnspecifiedPasswordIterationLimit uusi rajoitus. Jos haluat esimerkiksi asettaa iteraatioiden rajaksi 1 000 000 (miljoona) iteraatiota, suorita alla kuvatut komennot järjestelmänvalvojan oikeuksin suoritettavasta komentokehotteesta.
- Tämä luku määrittää iteraatioiden kokonaisrajan , joka on MAC-iteraatiomäärän, salatun kassakaapin sisällön ja suojellun pussin iteraatiomäärän summa. Jos olet vienyt PFX:n manuaalisesti käyttämällä eksplisiittistä iteraatiomäärän iter_count <> (esimerkiksi openssl pkcs12 -export -iter <iter_count>) -kautta) ja haluat tuoda kyseisen PFX-blob-objektin, aseta tämän rekisteriarvon arvoksi, joka on vähintään yhtä suuri kuin kaikkien odotettujen iteraatiokertojen summa. Käytännössä .NET Framework voi sallia iteraatioiden kokonaismäärän ylittää hieman tässä määritetyn rajoituksen.
- Rekisteriasetus on arkkitehtuuririippuvainen. Jotta sovellukset noudattavat määritettyä arvoa kohdearkkitehtuurista riippumatta, muista muokata sekä 32- että 64-bittisiä rekistereitä alla esitetyllä tavalla.
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
Jos haluat estää lisätarkistukset kokonaan, määritä rekisteriarvoksi -1 järjestelmänvalvojan oikeuksin suoritettavasta komentokehotteesta alla esitetyllä tavalla.
- ⚠️ Varoitus: Aseta rekisteriarvoksi -1 vain, jos olet varma, että kohdekoneessa suoritettavat palvelut eivät käsittele epäluotettavaa varmennesyötettä.
- Määritä sentinel-1 käyttämällä REG_SZ tyyppiä REG_DWORD tyypin sijaan. Rekisteriasetus on arkkitehtuuririippuvainen. Jotta sovellukset noudattavat määritettyä arvoa kohdearkkitehtuurista riippumatta, muista muokata sekä 32- että 64-bittisiä rekistereitä alla esitetyllä tavalla.
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
Voit kumota rekisterin muutokset poistamalla Pkcs12UnspecifiedPasswordIterationLimit -rekisteriarvon järjestelmänvalvojan oikeuksin suoritettavasta komentokehotteesta.
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:32
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:64
Windows-kohtaiset huomautukset
Windowsissa .NET Framework tuo varmenteita PFXImportCertStore-toiminnon kautta. Tämä funktio suorittaa oman vahvistuksensa, mukaan lukien asettamalla omat rajoituksensa PFX-blobin suurimmalle sallitulle iteraatiomäärälle. Nämä tarkistukset suoritetaan edelleen PFX-tuonnin yhteydessä. . Yllä kuvatut NET-kohtaiset ympäristömuuttujat ja rekisteriavaimet eivät vaikuta siihen, miten PFXImportCertStore suorittaa nämä tarkistukset.