W aktualizacji zbiorczej z listopada 2020 r. dla Windows 10 w wersji 2004 i nowszej, a także w styczniu 2021 r. w wersji zbiorczej pakietu zbiorczego aktualizacji zabezpieczeń i jakości dla .NET Framework 4.8 opublikowano zmianę w celu usprawnienia procesu oczyszczania certyfikatów X509Certificate2. Poniżej przedstawiono dodatkowe objaśnienia dotyczące okresu istnienia klucza prywatnego w systemie Windows.
Od .NET Framework 2.0 istnieją dwa różne sposoby ładowania certyfikatu i skojarzonego z nim klucza prywatnego z pliku PKCS#12 PFX: jako jeden obiekt certyfikatu za pośrednictwem elementów członkowskich klasy X509Certificate2 lub jako wszystkie certyfikaty obecne w PFX za pośrednictwem metod X509Certificate2Collection.Import.
Domyślnym zachowaniem jest załadowanie klucza prywatnego do trwałego (nazwanego) klucza za pośrednictwem jednej z bibliotek kryptograficznych systemu, która pośrednio zapisuje plik na dysku. Większość wywołujących ładujących pfx używa obiektu certyfikatu tylko tymczasowo, więc gdy .NET zwalnia zasoby natywne skojarzone z certyfikatem, usuwa również klucz prywatny. Główne wyjątki w tym zachowaniu to:
-
Flaga X509KeyStorageFlags.PersistKeySet, która powoduje, że plik jest zapisywany, ale nie usuwany,
-
Flaga X509KeyStorageFlags.EphemeralKetSet, która powoduje załadowanie klucza prywatnego do pamięci bez pliku kopii zapasowej,
-
Nieprawidłowe zakończenie procesu, które może wystąpić, gdy trwa oczekiwanie na kluczowe usunięcie.
Wbrew intuicji dwa różne sposoby ładowania certyfikatów zawsze używały różnych mechanizmów do śledzenia, gdy jest to odpowiedni moment na usunięcie klucza prywatnego. Podczas ładowania pojedynczego certyfikatu za pośrednictwem klasy X509Certificate2 jest używany znacznik, który jest widoczny tylko dla środowiska uruchomieniowego .NET i dotyczy tylko tego odwołania do jednego obiektu. Ładowanie pliku PFX przez X509Certificate2Collection.Import używa znacznika na natywnym obiekcie certyfikatu, co skutkuje udostępnianiem "odpowiedzialności za usunięcie" we wszystkich zarządzanych obiektach reprezentujących ten sam certyfikat natywny. Oznacza to, że nowy X509Certificate2(otherCert.Handle). Dispose() spowoduje usunięcie pliku klucza prywatnego podczas połączenia z Dispose(), jeśli otherCert został załadowany z PFX przez X509Certificate2Collection.Import, ale nie, jeśli został załadowany z PFX za pośrednictwem jakichkolwiek członków klasy X509Certificate2. Niektóre części programu .NET wewnętrznie tworzą nowe zarządzane obiekty X509Certificate2 na podstawie natywnych uchwytów certyfikatów, takich jak klasa X509Chain i metoda X509Certificate2Collection.Find. Te części struktury i wszelkie części, które bezpośrednio lub pośrednio z nich korzystają, mogą spowodować przedwczesne usunięcie klucza, ponieważ obiekty, które tworzą, pobierają śmieci.
W początkowej wersji .NET Framework 4.8 wprowadzono błąd, który powodował, że X509Certificate2Collection.Import nie stosował znacznika usuwania, nawet jeśli nie określono ani PersistKeySet, ani EphemeralKeySet. W styczniu 2021 r. firma .NET wydała poprawkę dotyczącą tego błędu w pakiecie zbiorczym aktualizacji zabezpieczeń i jakości ze stycznia 2021 r., aby zapobiec przypadkowej gromadzeniu się opuszczonych plików kluczy prywatnych. Wywołujący, na które ma wpływ ta poprawka, mogą określić flagę PersistKeySet, aby powrócić do (przypadkowo innego) zachowania .NET Framework 4.8 RTM, jednak spowoduje to gromadzenie plików, które należy rozwiązać za pomocą niestandardowej logiki oczyszczania.
X509Certificate2Collection.Import on .NET Core for Windows and .NET 5+ for Windows zachowuje się tak samo jak .NET Framework 2.0-4.7.2 (i .NET Framework 4.8 ze wszystkimi zastosowanymi aktualizacjami). Zespół programu .NET rozważa przejście na ulepszony projekt w wersji .NET 6 (lub w przyszłych wersjach), ale ta aktualizacja projektu nie będzie miała zastosowania do .NET Framework, .NET Core ani .NET 5.