Märkus. Parandatud 22. juunil 2023, et värskendada lahendus ja ajutised lahendused
Märkus. Muudetud 15. juunil 2023, et värskendada võimalusi 4 ja 5
Taust
13. juunil 2023 andis Microsoft välja .NET raamistik ja .NET-i turbevärskenduse, mis mõjutab seda, kuidas käitusaeg X.509 serte impordib. Nende muudatuste tõttu võib X.509 serdi importimine põhjustada CryptographicExceptioni stsenaariumides, kus importimine oleks õnnestunud enne värskendamist.
Selles dokumendis kirjeldatakse mõjutatud rakenduste jaoks saadaolevaid muudatusi ja lahendusi.
Mõjutatud tarkvara
- .NET raamistik 2.0
- .NET raamistik 4.6.2, 4.7, 4.7.1, 4.7.2
- .NET raamistik 4.8
- .NET raamistik 4.8.1
- .NET 6.0
- .NET 7.0
Mõjutatud API-d
- uus X509Certificate(bait[])
- X509Certificate.Import(bait[])
- uus X509Certificate2(bait[])
- X509Certificate2.Import(bait[])
- X509Certificate2Collection.Import(bait[])
Muutuse kirjeldus
Enne 13. juunit 2023 muudaks muudatus, kui .NET raamistik ja .NET esitatakse koos kahendserdi bloobiga importimiseks, .NET raamistik ja .NET delegeeriksid tavaliselt bloobi valideerimise ja importimise aluseks olevale operatsioonisüsteemile. Näiteks Windowsis toetuvad .NET raamistik ja .NET tavaliselt valideerimiseks ja importimiseks PFXImportCertStore API-le.
13. juuni 2023 seisuga muutub, kui .NET raamistik ja .NET esitatakse importimiseks kahendserdi bloobiga, .NET raamistik ja .NET teevad mõnel juhul enne bloobi andmist aluseks olevale operatsioonisüsteemile täiendava valideerimise. See täiendav valideerimine teeb mitmeid heuristilisi kontrolle, et teha kindlaks, kas sissetulev sert kulutaks importimisel pahatahtlikult ressursse. Kuna see on täiendav valideerimine väljaspool seda, mida aluseks olev opsüsteem tavaliselt teeks, võib see blokeerida serdi bloobid, mis oleksid edukalt imporditud enne 13. juunit 2023, muutuda.
Teadaolevad regressioonid
Kui X.509-sert on eksporditud PFX-bloobina, kasutades harva kõrget parooli iteratsioonide arvu, võib selle serdi importimine nurjuda. Enamik sertide ekspordivõimalusi kasutab iteratsioonide arvu vahemikus 2 000–10 000. Pärast turbevärskenduse rakendamist nurjub importimine sertide puhul, mille iteratsioonide arv on suurem kui 600 000.
Kui X.509 sert on eksporditud nullparooliga (nt paroolita või paroolita
X509Certificate.Export(X509ContentType.Pfx, (string)null)X509Certificate.Export(X509ContentType.Pfx)]), võib selle serdi importimine nurjuda.
Märkus.
Eespool nimetatud regressiooni käsitleti 22 . juunil 2023. aastal KB5028608 arutatud värskenduses.
Kui X.509 sert on eksporditud PFX-bloobina, kasutades Windowsi võimet kaitsta privaatvõtit SID-le, võib selle serdi importimine nurjuda. See mõjutab järgmisel viisil loodud PFX-bloobusid:
- Windowsi serdiekspordi viisardi kaudu ja määrates viisardis, et privaatvõti peaks olema kaitstud domeeni kasutajaga; või
- PowerShelli cmdlet-käsu Export-PfxCertificate kaudu, kus esitatakse selgesõnaline
-ProtectToargument; või -
certutili utiliidi kaudu, kus esitatakse selgesõnaline
-protecttoargument; või - PFXExportCertStoreEx API kaudu, kus on esitatud PKCS12_PROTECT_TO_DOMAIN_SIDS lipp.
Lahendused & ajutised lahendused
Olemas on mitu lahendust, olenevalt sellest, kas soovite teha suunatud muudatusi oma koodi üksikutel kõnesaitidel või muuta ühe rakenduse käitumist või teha arvutiüleseid muudatusi.
1. võimalus (eelistatud) – installige värskendatud paik
Märkus.
See on eelistatud variant, kuna see lahendab tavaliselt teatatud kliendi regressioonid ja ei nõua rakenduse koodi muutmist.
Rakendatavus. See suvand kehtib kõigi .NET raamistik ja .NET-i versioonide kohta.
Seda küsimust käsitleti 22. juuni 2023. aasta värskenduses, mida arutati KB5028608.
Microsoft soovitab klientidel, kes kogevad 13. juunil 2023 kasutusele võetud regressioone, proovida see värskendatud paik installida enne selles dokumendis loetletud lahenduste proovimist.
2. võimalus: kõnesaidi muutmine
Rakendatavus. See suvand kehtib kõigi .NET raamistik ja .NET-i versioonide kohta.
Mõelge järele, kas imporditav bloob on usaldusväärne. Näiteks kas bloob toodi usaldusväärsest asukohast (nt teie kontrolli all olevast andmebaasist või konfiguratsioonifailist) või edastati see autentimata või õigusteta kliendi võrgutaotluse kaudu?
Microsoft soovitab tungivalt, et te ei impordiks teile autentimata võiprivaatsete klientide pakutavaid PFX-bloobe, kuna need bloobid võivad sisaldada pahatahtlikke ressursside ammendumise käitumist.
Kui teil on vaja importida avaliku võtme serdi bloob, mille on teile andnud ebausaldusväärne osapool, saate sellise bloobi turvaliseks importimiseks kasutada järgmist koodi. See näidiskood kasutab meetodit GetCertContentType serdi bloobi aluseks oleva tüübi määramiseks ja PFX-bloobide hülgamiseks juhul, kui eeldate importida ainult avaliku võtme serdi bloobi.
X509Certificate2(byte[]) Konstruktor on ohutu kasutamiseks ebausaldusväärsete mitte-PFX-bloobide andmisel.
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);
}
}
Kui teil on vaja importida paroolita privaatvõtme serdi bloob ja olete kindlaks teinud, et bloob on usaldusväärne, saate 2023. aasta 13. juuniks läbi viidud täiendavaid valideerimiskontrolle tõkestada, kutsudes teise konstruktori ülekoormuse. Näiteks saate kutsuda konstruktori ülekoormuse, mis aktsepteerib stringiparooli argumenti ja edastab argumendi väärtuse jaoks tühiväärtuse.
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. võimalus: täiendava valideerimise muutmine või tõkestamine keskkonnamuutuja abil
Rakendatavus: see suvand kehtib ainult kõigi .NET raamistik versioonide kohta. See ei kehti .NET 6.0+ kohta.
Kuigi .NET raamistik vaikimisi piirata imporditoiminguid, et võtta paroolist kuni 600 000 iteratsiooni, saab selle piirangu konfigureerida rakenduseüleselt või masinüleselt, kasutades keskkonnamuutujat. See uus piirang kehtib kõigi eespool loetletud mõjutatud API-de kutsumise korral.
Limiidi muutmiseks määrake keskkonnamuutuja COMPlus_Pkcs12UnspecifiedPasswordIterationLimit väärtuseks uue piirangu väärtus. Näiteks 1 000 000 (miljoni) iteratsiooni piirmäära seadmiseks määrake keskkonnamuutuja, nagu allpool näidatud.
- See arv määrab iteratsiooni kogupiirangu , mis on MAC-iteratsioonide arvu, krüptitud turvaliste sisude ja pakitud koti iteratsioonide arvu summa. Kui olete PFX-i käsitsi eksportinud konkreetse iteratsiooniarvuga <iter_count> (nt via openssl pkcs12 -export -iter <iter_count>) ja soovite selle PFX-bloobi importida, määrake selle keskkonnamuutuja väärtuseks vähemalt sama suur kui kõigi oodatavate iteratsioonide summa. Praktikas võivad .NET raamistik ja .NET lubada iteratsioonide koguarvu veidi ületada mis tahes siin konfigureeritud otsest piirangut.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000
Täiendavate kontrollide täielikult tõkestamiseks seadke keskkonnamuutuja spetsiaalse sentineli väärtuseks -1, nagu allpool näidatud.
- ⚠️ Hoiatus. Määrake keskkonnamuutuja väärtuseks -1 ainult siis, kui olete kindel, et sihtrakendus ei töötle ebausaldusväärse serdi sisendit.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1
4. võimalus: täiendava valideerimise muutmine või tõkestamine AppContexti abil
Kohaldatavus. See suvand kehtib ainult versioonile .NET 6.0+. See ei kehti .NET raamistik
Kuigi .NET-i vaikimisi piiramise imporditoimingud ei võta üle 600 000 iteratsiooni parooli, saab selle piirangu konfigureerida kogu rakendust hõlmava lüliti AppContext abil. See uus piirang kehtib kõigi eespool loetletud mõjutatud API-de kutsumise korral.
Limiidi muutmiseks määrake AppContexti lüliti System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit uue piirangu väärtuseks. Näiteks 1 000 000 (miljoni) iteratsiooni piirangu seadmiseks määrake lüliti, nagu allpool näidatud.
- See arv määrab iteratsiooni kogupiirangu, mis on MAC-iteratsioonide arvu, krüptitud turvaliste sisude ja pakitud koti iteratsioonide arvu summa. Kui olete PFX-i käsitsi eksportinud konkreetse iteratsiooniarvuga <iter_count> (nt via openssl pkcs12 -export -iter <iter_count>) ja soovite selle PFX-bloobi importida, määrake selle keskkonnamuutuja väärtuseks vähemalt sama suur kui kõigi oodatavate iteratsioonide summa. Praktikas võib .NET lubada iteratsioonide koguarvu veidi ületada mis tahes siin konfigureeritud otsest piirangut.
Rakenduse projektifaili (.csproj või .vbproj) lüliti määramiseks tehke järgmist.
<!--
- See lüliti töötab ainult juhul, kui praegune projektifail tähistab rakendust. See ei mõjuta, kui praegune projektifail tähistab ühisteeki.
-->
<ItemGroup>
- <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="1000000" />
</ItemGroup>
Teise võimalusena saate samasse kausta paigutada faili nimega runtimeconfig.template.json järgmise sisuga, mis sisaldab teie rakenduse projektifaili.
{
"configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": 10000000
}
}
Lisateavet .NET-i käitusaja konfiguratsioonisätete muutmise kohta leiate dokumentatsioonilehelt .NET Runtime'i konfigureerimissätted.
Täiendavate kontrollide täielikult tõkestamiseks määrake konfiguratsioonilüliti sentineli eriväärtus -1, nagu allpool näidatud.
⚠️ Hoiatus: määrake lüliti AppContext väärtuseks -1 ainult siis, kui olete kindel, et sihtrakendus ei töötle ebausaldusväärse serdi sisendit.
Rakenduse projektifailis (.csproj või .vbproj) tehke järgmist.
<!--
- See lüliti töötab ainult juhul, kui praegune projektifail tähistab rakendust. See ei mõjuta, kui praegune projektifail tähistab ühisteeki.
-->
<ItemGroup>
- <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="-1" />
</ItemGroup>
Või runtimeconfig.template.json failis:
{
- "configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": -1
}
}
5. võimalus: täiendava valideerimismasina muutmine või tõkestamine registri kaudu (Windows-only for .NET raamistik)
Rakendatavus: see suvand kehtib ainult kõigi .NET raamistik versioonide kohta. See ei kehti .NET 6.0+ kohta.
Kuigi .NET raamistik vaikimisi piirata imporditoiminguid, et võtta paroolist kuni 600 000 iteratsiooni, saab selle piirangu HKLM-i registri abil konfigureerida kogu arvutis. See uus piirang kehtib kõigi eespool loetletud mõjutatud API-de kutsumise korral.
Limiidi muutmiseks määrake registrivõtme HKLM\Software\Microsoft\.NETFrameworkall uue piirangu väärtus Pkcs12UnspecifiedPasswordIterationLimit . Näiteks 1 000 000 (miljoni) iteratsiooni määramiseks käivitage käsud, nagu allpool näidatud ülemaõigustega käsuviibast.
- See arv määrab iteratsiooni kogupiirangu , mis on MAC-iteratsioonide arvu, krüptitud turvaliste sisude ja pakitud koti iteratsioonide arvu summa. Kui olete PFX-i käsitsi eksportinud konkreetse iteratsiooniarvuga <iter_count> (nt via openssl pkcs12 -export -iter <iter_count>) ja soovite importida selle PFX-i bloobi, määrake selle registriväärtuse väärtuseks vähemalt sama suur kui kõigi oodatavate iteratsioonide summa. Praktikas võib .NET raamistik lubada iteratsioonide koguarvu veidi ületada siin konfigureeritud otsest piirangut.
- Registrisäte sõltub arhitektuurist. Tagamaks, et rakendused jälgivad teie konfigureeritud väärtust olenemata sihtarhitektuurist, muutke kindlasti nii 32-bitiseid kui ka 64-bitiseid registriid, nagu allpool näidatud.
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
Täiendavate kontrollide täielikult tõkestamiseks määrake ülemaõigustega käsuviiba registriväärtuseks -1, nagu allpool näidatud.
- ⚠️ Hoiatus. Määrake registri väärtuseks -1 ainult juhul, kui olete kindel, et sihtarvutis töötavad teenused ei töötle ebausaldusväärse serdi sisendit.
- Sentineli -1 määramiseks kasutage tüübi REG_DWORD asemel REG_SZ tüüpi. Registrisäte sõltub arhitektuurist. Tagamaks, et rakendused jälgivad teie konfigureeritud väärtust olenemata sihtarhitektuurist, muutke kindlasti nii 32-bitiseid kui ka 64-bitiseid registriid, nagu allpool näidatud.
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
Registrimuudatuste ennistamiseks kustutage ülemaõigustes käsuviibast reg-väärtus Pkcs12UnspecifiedPasswordIterationLimit.
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:32
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:64
Windowsi-kohased märkmed
Windowsis .NET raamistik impordiserdid funktsiooni PFXImportCertStore kaudu. See funktsioon teostab oma valideerimise, sealhulgas seab PFX-i bloobi maksimaalsele lubatud iteratsiooniarvule oma piirangud. Need kontrollid toimuvad endiselt PFX-importimisel. . Eespool kirjeldatud NET-i-kohased keskkonnamuutujad ja registrivõtmed ei mõjuta seda, kuidas PFXImportCertStore neid kontrolle teeb.