Compartilhar via


Instalar um arquivo PFX usando X509Certificate de um aplicativo .NET padrão

Este artigo ajuda você a resolver exceções ao instalar um arquivo PFX usando X509Certificate um aplicativo .NET padrão.

Versão original do produto: .NET Framework
Número original do KB: 950090

Sintoma

Um aplicativo .NET padrão tenta instalar um certificado em um arquivo PFX (PKCS12) programaticamente usando a X509Certificate classe or X509Certificate2 com código, como no exemplo a seguir:

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

ou

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

O seguinte tipo de exceção ocorrerá quando você tentar usar a chave privada do certificado em outro aplicativo:

Exceção não tratada: System.Security.Cryptography.CryptographicException: O conjunto de chaves não existe
em System.Security.Cryptography.Utils.CreateProvHandle (parâmetros CspParameters, randomKeyContainer booleano)
em System.Security.Cryptography.Utils.GetKeyPairHelper (CspAlgorithmType keyType, parâmetros CspParameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle & safeProvHandle, SafeKeyHandle & safeKeyHandle)
em System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair ()
em System.Security.Cryptography.RSACryptoServiceProvider.. ctor(Int32 dwKeySize, parâmetros CspParameters, uso booleanoDefaultKeySize)
em System.Security.Cryptography.RSACryptoServiceProvider.. ctor(parâmetros CspParameters)
em System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
em UseCertPrivateKey.Program.Main (String [] args) em C: \ UseCertPrivateKey \ Program.cs: linha 20

Motivo

Quando o certificado é instalado usando a X509Certificate classe or X509Certificate2 ouX509Certificate, por padrão, X509Certificate2 cria um contêiner temporário para importar a chave privada. A chave privada é excluída quando não há mais uma referência à chave privada.

Resolução

Para criar um contêiner de chave permanente para a chave privada, o X509KeyStorageFlags.PersistKeySet sinalizador deve ser usado para impedir que o .NET exclua o contêiner de chave. Em vez disso, o código a seguir deve ser usado.

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

ou

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);