Duración simplificada de la clave privada de Windows
Cuando una carga de trabajo carga un PKCS#12/PFX en Windows sin establecer las opciones de almacenamiento PersistKeySet o EphemeralKeySet, .NET determina cuándo ya no se necesita la clave privada y se debe borrar. En versiones anteriores de .NET (y en .NET Framework), se usaron dos conjuntos de lógica diferentes. En .NET 9, hay un único conjunto de lógica.
Comportamiento anterior
Antes, al cargar un certificado (y su clave privada) desde un PKCS#12/PFX con new X509Certificate2(pfx, password, flags)
, el certificado cargado representaba la duración de la clave privada. Cuando se eliminaba este objeto de certificado (o finalizaba si se recolectaba de los elementos no utilizados sin eliminarse), se eliminaba la clave privada asociada. No se producía ninguna propiedad compartida ni transferencia de propiedad.
Al cargar un certificado (y su clave privada) desde un PKCS#12/PFX con X509Certificate2Collection.Import(pfx, password, flags)
, cada certificado cargado que tenía una clave privada realizaba un seguimiento de la duración, como con la carga de certificado único. Pero, además, se colocaba un marcador en la copia nativa del certificado para indicar que las copias también debían realizar un seguimiento de la duración de la clave privada. Si se creaba un segundo objeto X509Certificate2 en términos del mismo valor PCERT_CONTEXT
subyacente, la copia eliminada (o finalizada) borraba primero la clave privada debajo de la otra copia.
El código siguiente fallaba (ya sea con o CryptographicException ) NullReferenceExceptionporque se eliminaba la clave privada:
X509Certificate2Collection coll = new X509Certificate2Collection(pfx, password, X509KeyStorageFlags.DefaultKeySet);
X509Certificate2Collection coll2 = coll.Find(X509FindType.FindBySubjectName, "", false);
coll2 = null;
GC.Collect();
GC.WaitForPendingFinalizers();
using (RSA key = coll[0].GetRSAPrivateKey())
{
key.SignData(pfx, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
}
Comportamiento nuevo
A partir de .NET 9, la duración siempre está asociada a la instancia X509Certificate2 que se generó directamente a partir de la carga PKCS#12/PFX.
El mismo fragmento de código de la sección Comportamiento anterior ahora se realiza correctamente.
Versión introducida
.NET 9 (versión preliminar 7)
Tipo de cambio importante
Este es un cambio de funcionamiento.
Motivo del cambio
La mayoría de las cargas de trabajo que cargan un PKCS#12/PFX usan la carga de certificado único y comprenden la mecánica de duración asociada a ese método. La mecánica asociada a la carga de recopilación a menudo era sorprendente y, a veces, provocaba la eliminación prematura de claves.
Acción recomendada
Si entendió la administración de la duración de la carga de la colección y dependía de llamar a Dispose
en un clon para provocar la eliminación de claves, asegúrese de que también está llamando a Dispose
en el objeto cargado original.