Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article helps you resolve exceptions when you install a PFX file by using X509Certificate
from a standard .NET application.
Original product version: .NET Framework
Original KB number: 950090
Symptom
A standard .NET application tries to install a certificate in a PFX file (PKCS12) programmatically by using the X509Certificate
or X509Certificate2
class with code like the following example:
X509Certificate2 cert = new X509Certificate2("a.pfx", "password");
X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
or
X509Certificate2 cert = new X509Certificate2("a.pfx", "password", X509KeyStorageFlags.MachineKeySet);
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(xCertificate);
The following type of exception will occur when you try to use the certificate's private key within another application:
Unhandled Exception: System.Security.Cryptography.CryptographicException: Keyset does not exist
at System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer)
at System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize)
at System.Security.Cryptography.RSACryptoServiceProvider..ctor(CspParameters parameters)
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
at UseCertPrivateKey.Program.Main(String[] args) in C:\UseCertPrivateKey\Program.cs:line 20
Cause
When the certificate is installed by using the X509Certificate
or X509Certificate2
class, X509Certificate
or X509Certificate2
by default creates a temporary container to import the private key. The private key is deleted when there's no longer a reference to the private key.
Resolution
To create a permanent key container for the private key, the X509KeyStorageFlags.PersistKeySet
flag must be used to prevent .NET from deleting the key container. The following code should be used instead.
X509Certificate2 cert = new X509Certificate2("a.pfx", "password", X509KeyStorageFlags.PersistKeySet);
X509Store store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
or
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);