Bemærk: Revideret 22. juni 2023 for at opdatere opløsning og løsninger
Bemærk: Revideret 15. juni 2023 for at opdatere løsningen omkring mulighed 4 og 5
Baggrund
Den 13. juni 2023 udgav Microsoft en sikkerhedsopdatering til .NET Framework og .NET, som påvirker, hvordan runtime importerer X.509-certifikater. Disse ændringer kan medføre, at import af X.509-certifikater udløser CryptographicException i scenarier, hvor importen ville være lykkedes før opdateringen.
I dette dokument beskrives de ændringer og løsninger, der er tilgængelige for påvirkede programmer.
Påvirket software
- .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
Påvirkede API'er
- new X509Certificate(byte[])
- X509Certificate.Import(byte[])
- new X509Certificate2(byte[])
- X509Certificate2.Import(byte[])
- X509Certificate2Collection.Import(byte[])
Beskrivelse af ændring
Før ændringen den 13. juni 2023, når .NET Framework og .NET præsenteres for en binær certifikatblob til import, vil .NET Framework og .NET typisk uddelegere validering og import af blobben til det underliggende operativsystem. På Windows vil .NET Framework og .NET f.eks. typisk være afhængige af PFXImportCertStore-API'en til validering og import.
Fra og med ændringen den 13. juni 2023 udfører .NET Framework og .NET i nogle tilfælde yderligere validering, før blob'en overdrages til det underliggende operativsystem, når .NET Framework og .NET præsenteres for en binær certifikatblob til import. Denne yderligere validering udfører en række heuristiske kontroller for at afgøre, om det indgående certifikat ondsindet ville opbruge ressourcer ved import. Da dette er yderligere validering ud over, hvad det underliggende operativsystem normalt ville udføre, kan det blokere certifikatblobs, som ville være blevet importeret før ændringen den 13. juni 2023.
Kendte regressioner
Hvis et X.509-certifikat er blevet eksporteret som en PFX-blob ved hjælp af et ualmindeligt højt antal gentagelser af adgangskoder, kan certifikatet nu ikke importeres. De fleste faciliteter til certifikateksport bruger et iterationsantal et sted mellem 2.000 og 10.000. Når sikkerhedsopdateringen er installeret, mislykkes importen for certifikater, der indeholder et gentagelsesantal, der er større end 600.000.
Hvis et X.509-certifikat er blevet eksporteret ved hjælp af en null-adgangskode [f.eks. via
X509Certificate.Export(X509ContentType.Pfx, (string)null)eller uden adgangskodeX509Certificate.Export(X509ContentType.Pfx)], kan certifikatet nu ikke importeres.
Bemærk
Ovenstående regression er blevet behandlet i opdateringen fra 22. juni 2023, der blev beskrevet i KB5028608.
Hvis et X.509-certifikat er blevet eksporteret som en PFX-blob ved hjælp af Windows' funktionalitet til at beskytte den private nøgle til et SID, kan certifikatet nu ikke importeres. Dette påvirker PFX-blobs, der oprettes på følgende måder:
- Via Windows's Guiden Certifikateksport og angive i guiden, at den private nøgle skal beskyttes for en domænebruger; eller
- Via PowerShell's Export-PfxCertificate-cmdlet , hvor der angives et eksplicit
-ProtectToargument; eller - Via certifikatværktøjet , hvor der leveres et eksplicit
-protecttoargument; eller - Via PFXExportCertStoreEx-API'et , hvor det PKCS12_PROTECT_TO_DOMAIN_SIDS flag er angivet.
Løsning & midlertidige løsninger
Der findes forskellige løsninger, afhængigt af om du vil foretage målrettede ændringer på individuelle kaldewebsteder inden for din kode, eller du vil ændre funktionsmåden for et enkelt program, eller du vil foretage ændringer for hele computeren.
Mulighed 1 (foretrukket) – Installér en opdateret programrettelse
Bemærk
Dette er den foretrukne indstilling, da den løser ofte rapporterede kunderegressioner og ikke kræver kodeændringer i programmet.
Anvendelighed: Denne indstilling gælder for alle versioner af .NET Framework og .NET.
Dette problem er blevet løst i opdateringen fra 22. juni 2023, der er beskrevet i KB5028608.
Microsoft anbefaler, at kunder, der oplever regressioner, der er introduceret af udgivelsen den 13. juni 2023, forsøger at installere denne opdaterede programrettelse, før de forsøger de løsninger, der er angivet senere i dette dokument.
Mulighed 2 – Ændring af opkaldets websted
Anvendelighed: Denne indstilling gælder for alle versioner af .NET Framework og .NET.
Overvej, om den blob, du importerer, er pålidelig. Blev blob'en f.eks. hentet fra en pålidelig placering, såsom en database eller konfigurationsfil under din kontrol, eller blev den leveret via en netværksanmodning fra en ikke-godkendt eller ikke-privilegeret klient?
Microsoft anbefaler på det kraftigste, at du ikke importerer PFX-blobs, som du får fra ikke-godkendte eller ikke-privilegerede klienter, da disse blobs kan indeholde adfærd på skadelig ressourceoverbelastning.
Hvis du vil importere en BLOB med en offentlig nøgle-certifikat , som du har fået af en part, der ikke er tillid til, kan du bruge følgende kode til sikkert at importere en sådan blob. Denne eksempelkode bruger metoden GetCertContentType til at bestemme, hvad den underliggende type certifikatblob er, og den afviser PFX-blobs i tilfælde, hvor du kun forventer at importere en offentlig nøgle-certifikatblob. Konstruktøren X509Certificate2(byte[]) er sikker at bruge, når den får ikke-PFX-blobs, der ikke er tillid til.
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);
}
}
Hvis du har brug for at importere en adgangskodefri privat nøgle-certifikat-blob, og du har fastslået, at blob'en er pålidelig, kan du undertrykke de yderligere valideringskontroller, der er udført af sikkerhedsudgivelsen fra 13. juni 2023, ved at kalde en anden konstruktøroverbelastning. Du kan f.eks. kalde konstruktøroverbelastning, som accepterer et strengadgangskodeargument og videregive null for argumentværdien.
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);
Løsning 3 – Ændring eller undertrykkelse af yderligere validering ved hjælp af en miljøvariabel
Anvendelighed: Denne indstilling gælder kun for alle versioner af .NET Framework. Den gælder ikke for .NET 6.0+.
Mens .NET Framework som standard begrænser importhandlinger til højst 600.000 gentagelser af en adgangskode, kan denne grænse konfigureres på app- eller computerbasis ved hjælp af en miljøvariabel. Denne nye grænse gælder for alle aktiveringer af de berørte API'er, der er angivet ovenfor.
Hvis du vil ændre grænsen, skal du angive miljøvariablen COMPlus_Pkcs12UnspecifiedPasswordIterationLimit til værdien for, hvad den nye grænse skal være. Hvis du f.eks. vil angive grænsen til 1.000.000 (en million) gentagelser, skal du angive miljøvariablen som vist nedenfor.
- Dette tal styrer den samlede gentagelsesgrænse, som er summen af antallet af MAC-gentagelser, krypteret sikkert indhold og indkapslet bagages gentagelsesantal. Hvis du har eksporteret en PFX manuelt ved hjælp af et eksplicit antal <gentagelser iter_count> (f.eks. via openssl pkcs12 -export -iter <iter_count>) og vil importere den pågældende PFX-blob, skal du indstille denne miljøvariabel til en værdi, der er mindst lige så stor som summen af alle forventede gentagelser. I praksis kan .NET Framework og .NET tillade, at det samlede antal gentagelser en smule overskrider en eventuel eksplicit grænse, der er konfigureret her.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000
For at skjule de yderligere kontroller fuldstændigt skal du indstille miljøvariablen til den særlige Sentinel-værdi -1, som vist nedenfor.
- ⚠️ Advarsel: Angiv kun miljøvariabelværdien til -1, hvis du er sikker på, at destinationsprogrammet ikke håndterer certifikatinput, der ikke er tillid til.
COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1
Løsning 4 – Ændring eller undertrykkelse af yderligere validering ved hjælp af AppContext
Anvendelighed: Denne indstilling gælder kun for .NET 6.0+. Den gælder ikke for .NET Framework
Mens .NET som standard begrænser importhandlinger til højst 600.000 gentagelser af en adgangskode, kan denne grænse konfigureres for hele programmet ved hjælp af parameteren AppContext. Denne nye grænse gælder for alle aktiveringer af de berørte API'er, der er angivet ovenfor.
Hvis du vil ændre grænsen, skal du angive parameteren AppContext System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit til værdien for, hvad den nye grænse skal være. Hvis du f.eks. vil angive grænsen til 1.000.000 (en million) gentagelser, skal du angive skiftet som vist nedenfor.
- Dette tal styrer den samlede gentagelsesgrænse, som er summen af antallet af MAC-gentagelser, krypteret sikkert indhold og indkapslet bagages gentagelsesantal. Hvis du har eksporteret en PFX manuelt ved hjælp af et eksplicit antal <gentagelser iter_count> (f.eks. via openssl pkcs12 -export -iter <iter_count>) og vil importere den pågældende PFX-blob, skal du indstille denne miljøvariabel til en værdi, der er mindst lige så stor som summen af alle forventede gentagelser. I praksis kan .NET tillade, at det samlede antal gentagelser en smule overskrider en eventuel eksplicit grænse, der er konfigureret her.
Sådan indstiller du skiftet i dit programs projektfil (.csproj eller .vbproj):
<!--
- Dette parameter fungerer kun, hvis den aktuelle projektfil repræsenterer et program. Det har ingen betydning, hvis den aktuelle projektfil repræsenterer et delt bibliotek.
-->
<ItemGroup>
- <RuntimeHostConfigurationOption include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" value="1000000" />
</ItemGroup>
Du kan også placere en fil med navnet runtimeconfig.template.json med følgende indhold i den samme mappe, som indeholder dit programs projektfil:
{
"configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": 1000000
}
}
Du kan finde flere oplysninger om ændring af konfigurationsindstillinger for .NET-kørsel på siden med dokumentation Konfigurationsindstillinger for .NET-kørsel.
For helt at undertrykke de yderligere kontroller skal du indstille konfigurationskontakten til den specielle sentinelværdi -1, som vist nedenfor.
⚠️ Advarsel: Indstil kun parameteren AppContext til -1, hvis du er sikker på, at destinationsprogrammet ikke håndterer certifikatinput, der ikke er tillid til.
I programmets projektfil (.csproj eller .vbproj):
<!--
- Dette parameter fungerer kun, hvis den aktuelle projektfil repræsenterer et program. Det har ingen betydning, hvis den aktuelle projektfil repræsenterer et delt bibliotek.
-->
<ItemGroup>
- <RuntimeHostConfigurationOption include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" value="-1" />
</ItemGroup>
Eller i den runtimeconfig.template.json fil:
{
- "configProperties": {
- "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": -1
}
}
Løsning 5 – Ændring eller undertrykkelse af yderligere validering på hele computeren via registreringsdatabasen (kun Windows til .NET Framework)
Anvendelighed: Denne indstilling gælder kun for alle versioner af .NET Framework. Den gælder ikke for .NET 6.0+.
Mens .NET Framework som standard begrænser importhandlinger til højst 600.000 gentagelser af en adgangskode, kan denne grænse konfigureres på tværs af computeren ved hjælp af HKLM-registreringsdatabasen. Denne nye grænse gælder for alle aktiveringer af de berørte API'er, der er angivet ovenfor.
Hvis du vil ændre grænsen, skal du angive værdien Pkcs12UnspecifiedPasswordIterationLimit til hvad den nye grænse skal være under registreringsdatabasenøglenHKLM\Software\Microsoft\.NETFramework. Hvis du f.eks. vil angive grænsen til 1.000.000 (en million) gentagelser, skal du køre kommandoerne som vist nedenfor fra en kommandoprompt med administratorrettigheder.
- Dette tal styrer den samlede gentagelsesgrænse, som er summen af antallet af MAC-gentagelser, krypteret sikkert indhold og indkapslet bagages gentagelsesantal. Hvis du har eksporteret en PFX manuelt ved hjælp af et eksplicit gentagelsesantal <iter_count> (f.eks. via openssl pkcs12 -export -iter <iter_count>) og ønsker at importere den pågældende PFX-blob, skal du angive denne værdi i registreringsdatabasen til en værdi, der er mindst lige så stor som summen af alle forventede gentagelser. I praksis kan .NET Framework tillade, at det samlede antal gentagelser en smule overskrider en eventuel eksplicit grænse, der er konfigureret her.
- Indstillingen i registreringsdatabasen afhænger af arkitekturen. For at sikre, at programmer overholder din konfigurerede værdi uanset deres destinationsarkitektur, skal du huske at ændre både 32-bit- og 64-bit-registret, sådan som det er vist nedenfor.
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
Du kan helt skjule de yderligere kontroller ved at angive registreringsdatabaseværdien til -1 fra en kommandoprompt med administratorrettigheder, som vist nedenfor.
- ⚠️ Advarsel: Angiv kun registreringsdatabaseværdien til -1, hvis du er sikker på, at de tjenester, der kører på destinationscomputeren, ikke håndterer certifikatinput, der ikke er tillid til.
- Hvis du vil indstille sentinel-værdien -1, skal du bruge typen REG_SZ i stedet for typen REG_DWORD. Indstillingen i registreringsdatabasen afhænger af arkitekturen. For at sikre, at programmer overholder din konfigurerede værdi uanset deres destinationsarkitektur, skal du huske at ændre både 32-bit- og 64-bit-registret, sådan som det er vist nedenfor.
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
Hvis du vil gendanne ændringerne i registreringsdatabasen, skal du slette registreringsdatabaseværdien Pkcs12UnspecifiedPasswordIterationLimit fra en kommandoprompt med administratorrettigheder.
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:32
reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:64
Windows-specifikke noter
I Windows importerer .NET Framework certifikater via funktionen PFXImportCertStore. Denne funktion udfører sin egen validering, herunder at sætte sine egne grænser for et PFX-blobs maksimalt tilladte antal gentagelser. Denne kontrol vil stadig finde sted ved PFX-import. Den . NET-specifikke miljøvariabler og registreringsdatabasenøgler, der er beskrevet ovenfor, påvirker ikke, hvordan PFXImportCertStore udfører disse kontroller.