La préversion de la mise à jour cumulative de novembre 2020 pour Windows 10 version 2004 et antérieure, ainsi que la version du correctif cumulatif de sécurité et de qualité de janvier 2021 pour .NET Framework 4.8 ont publié une modification visant à améliorer le processus de propre pour les certificats X509Certificate2. Ci-dessous, nous fournissons des clarifications supplémentaires sur la durée de vie d’une clé privée sur Windows.
Depuis .NET Framework 2.0, il existe deux façons de charger un certificat et sa clé privée associée à partir d’un fichier PFX PKCS#12 : en tant qu’objet de certificat via les membres de la classe X509Certificate2 ou en tant que tous les certificats présents dans le PFX via les méthodes X509Certificate2Collection.Import.
Le comportement par défaut est que la clé privée est chargée dans une clé persistante (nommée) via l’une des bibliothèques de chiffrement système, qui écrit indirectement un fichier sur le disque. La plupart des appelants qui chargent un PFX utilisent uniquement l’objet de certificat temporairement. Par conséquent, lorsque .NET libère les ressources natives associées au certificat, il supprime également la clé privée. Les exceptions main à ce comportement sont
-
L’indicateur X509KeyStorageFlags.PersistKeySet, qui entraîne l’écriture du fichier, mais pas la suppression,
-
L’indicateur X509KeyStorageFlags.EphemeralKetSet, qui entraîne le chargement de la clé privée en mémoire sans fichier de stockage,
-
Arrêt anormal du processus, qui peut se produire lorsque la suppression de clé est en attente.
Contre-intuitivement, les deux différentes façons de charger des certificats ont toujours utilisé différents mécanismes pour le suivi lorsqu’il est approprié de supprimer la clé privée. Le chargement d’un certificat unique via la classe X509Certificate2 utilise un marqueur qui n’est visible que pour le runtime .NET et s’applique uniquement à cette référence d’objet. Le chargement d’un PFX via X509Certificate2Collection.Import utilise un marqueur sur l’objet de certificat natif, ce qui entraîne le partage de la « responsabilité de suppression » entre tous les objets managés qui représentent le même certificat natif. Cela signifie que le nouveau X509Certificate2(otherCert.Handle). Dispose() entraîne l’effacement du fichier de clé privée lors de l’appel à Dispose() si otherCert a été chargé à partir d’un PFX via X509Certificate2Collection.Import, mais pas s’il a été chargé à partir d’un PFX via des membres de classe X509Certificate2. Certaines parties de .NET créent en interne des objets X509Certificate2 managés à partir de handles de certificat natifs, tels que la classe X509Chain et la méthode X509Certificate2Collection.Find. Ces parties de l’infrastructure, et toutes les parties qui les utilisent directement ou indirectement, peuvent entraîner l’effacement prématuré de la clé à mesure que les objets qu’ils créent sont récupérés par la mémoire.
Un bogue a été introduit dans la version initiale de .NET Framework 4.8, ce qui a conduit À X509Certificate2Collection.Import à ne pas appliquer le marqueur de suppression même si ni PersistKeySet ni EphemeralKeySet n’ont été spécifiés. .NET a publié un correctif pour ce bogue dans le correctif cumulatif de sécurité et de qualité de janvier 2021 pour empêcher l’accumulation involontaire de fichiers de clé privée abandonnés. Les appelants concernés par ce correctif peuvent spécifier l’indicateur PersistKeySet pour revenir au comportement RTM (involontairement différent) de .NET Framework 4.8, bien que cela entraîne une accumulation de fichiers qui doit être traitée avec une logique de nettoyage personnalisée.
X509Certificate2Collection.Import sur .NET Core pour Windows et .NET 5+ pour Windows se comporte de la même façon que .NET Framework 2.0-4.7.2 (et .NET Framework 4.8 avec toutes les mises à jour appliquées). L’équipe .NET envisage de passer à une conception améliorée dans .NET 6 (ou les versions ultérieures), mais cette mise à jour de conception ne s’appliquera pas à .NET Framework, .NET Core ou .NET 5.