Compartir vía


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.

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.

API afectadas