Instalar un archivo PFX mediante X509Certificate desde una aplicación .NET estándar

Este artículo le ayuda a resolver excepciones al instalar un archivo PFX mediante X509Certificate una aplicación .NET estándar.

Versión del producto original:   .NET Framework
Número KB original:   950090

Síntoma

Una aplicación .NET estándar intenta instalar un certificado en un archivo PFX (PKCS12) mediante programación mediante el uso de la clase or con código como X509Certificate X509Certificate2 el siguiente ejemplo:

X509Certificate2 cert = new X509Certificate2("a.pfx", "password");
X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);

o

X509Certificate2 cert = new X509Certificate2("a.pfx", "password", X509KeyStorageFlags.MachineKeySet);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(xCertificate);

El siguiente tipo de excepción se producirá cuando intente usar la clave privada del certificado en otra aplicación:

Excepción no controlada: System.Security.Cryptography.CryptographicException: Keyset no existe
en System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
en System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
en System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
en System.Security.Cryptography.RSACryptoServiceProvider.. ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
en System.Security.Cryptography.RSACryptoServiceProvider.. ctor(CspParameters parameters)
en System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
en UseCertPrivateKey.Program.Main(String[] args) en C: \ UseCertPrivateKey\Program.cs:line 20

Causa

Cuando el certificado se instala mediante la clase or, o de forma predeterminada crea un contenedor X509Certificate temporal para importar la clave X509Certificate2 X509Certificate X509Certificate2 privada. La clave privada se elimina cuando ya no hay una referencia a la clave privada.

Solución

Para crear un contenedor de claves permanente para la clave privada, la marca debe usarse para evitar X509KeyStorageFlags.PersistKeySet que .NET elimine el contenedor de claves. En su lugar, se debe usar el siguiente código.

X509Certificate2 cert = new X509Certificate2("a.pfx", "password", X509KeyStorageFlags.PersistKeySet);
X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);

o

X509Certificate2 cert = new X509Certificate2("a.pfx", "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(xCertificate);