Levetid for privat nøgle på Windows og sikkerheds- og kvalitetsopdatering af .NET Framework fra januar 2021

Forhåndsvisningen af den kumulative opdatering fra november 2020 til Windows 10 version 2004 og ældre samt sikkerheds- og kvalitetsopdateringen for januar 2021 til .NET Framework 4.8 udgav en ændring for at forbedre oprydningsprocessen for X509Certificate2-certifikater. Nedenfor giver vi yderligere afklaringer af en privat nøgles levetid på Windows.

Siden .NET Framework 2.0 har der været to forskellige måder at indlæse et certifikat og den tilknyttede private nøgle fra en PKCS#12 PFX-fil: som ét certifikatobjekt via medlemmer i klassen X509Certificate2 eller som alle certifikater, der findes i PFX, via metoderne X509Certificate2Collection.Import.

Standardfunktionsmåden er, at den private nøgle indlæses i en permanent (navngivet) nøgle via et af systemets kryptografibiblioteker, som indirekte skriver en fil til disken.  De fleste kaldere, der indlæser en PFX, bruger kun certifikatobjektet midlertidigt, så når .NET frigiver de oprindelige ressourcer, der er knyttet til certifikatet, slettes den private nøgle også.  De vigtigste undtagelser til denne funktionsmåde er

  1. Flaget X509KeyStorageFlags.PersistKeySet, som fører til, at filen skrives, men ikke slettes,
  2. Flaget X509KeyStorageFlags.EphemeralKetSet, som medfører, at den private nøgle indlæses i hukommelsen uden nogen backup-fil,
  3. Unormal procesafslutning, som kan forekomme, når en nøgle afventer sletning.

Kontraintuitivt har de to forskellige måder at indlæse certifikater på altid brugt forskellige mekanismer til at registrere, hvornår det er et passende tidspunkt at slette den private nøgle.  Indlæsning af et enkelt certifikat via klassen X509Certificate2 anvender en markør, der kun er synlig for .NET-kørslen og kun gælder for den ene objektreference.  Indlæsning af en PFX via X509Certificate2Collection.Import bruger en markør på det oprindelige certifikatobjekt, hvilket fører til, at "sletningsansvar" deles på tværs af alle administrerede objekter, der repræsenterer det samme oprindelige certifikat.  Det betyder, at det nye X509Certificate2(otherCert.Handle). Dispose() medfører, at den private nøglefil slettes under kaldet til Dispose(), hvis otherCert blev indlæst fra en PFX via X509Certificate2Collection.Import, men ikke hvis den blev indlæst fra en PFX via medlemmer af X509Certificate2-klassen.  Nogle dele af .NET opretter internt nye administrerede X509Certificate2-objekter fra oprindelige certifikathandles, f.eks. X509Chain-klassen og metoden X509Certificate2Collection.Find.  Disse dele af strukturen, og alle dele, der direkte eller indirekte bruger dem, kan resultere i for tidlig sletning af nøgler, da de objekter, de opretter, bliver indsamlet affald.

Der blev introduceret en fejl i den første version af .NET Framework 4.8, hvilket medførte, at X509Certificate2Collection.Import ikke anvendte sletningsmarkøren, selvom hverken PersistKeySet eller EphemeralKeySet var angivet. .NET udgav en rettelse til denne fejl i sikkerheds- og kvalitetsopdateringspakken for januar 2021 for at forhindre utilsigtet ophobning af efterladte private nøglefiler.  Opkaldere, der påvirkes af denne rettelse, kan angive flaget PersistKeySet for at vende tilbage til den (utilsigtet anderledes) .NET Framework 4.8 RTM-funktion, selvom dette vil resultere i filakkumulering, der skal løses med brugerdefineret oprydningslogik.

X509Certificate2Collection.Import på .NET Core til Windows og .NET 5+ til Windows fungerer på samme måde som .NET Framework 2.0-4.7.2 (og .NET Framework 4.8 med alle opdateringer anvendt).  .NET-teamet overvejer at skifte til et forbedret design i .NET 6 (eller fremtidige versioner), men denne designopdatering gælder ikke for .NET Framework, .NET Core eller .NET 5.