.NET Framework x509Certificate2 Class, HasPrivateKey == true && PrivateKey == null?


I’m attempting to work with an X509 certificate that was originally imported into the CurrentUser keystore on a Windows 10 computer using the “Certificates” snap-in of an MMC. The same procedure has been tested on a Windows 8.1 computer with the same result.

Using the standard PowerShell PKI module, I’m getting an X509Certificate2 object using Get-Item:

The output of $my_cert | fl * is as follows:

So HasPrivateKey == True, but PrivateKey == null. I’ve been trying to figure out how to gain access to the private key to perform encryption and decryption. The examples I’ve seen online all seem to indicate the PrivateKey property of the X509Certificate2 class should be readily available, but apparently I’ve missed something.

I’ve read similar questions here, such as Empty PrivateKey in x509certificate2, but none seem to resolve my issue. I’ve also read Eight tips for working with X.509 certificates in .NET by Paul Stovell, which was very enlightening, but ultimately didn’t help. It did help me verify that the Private Key exists in the correct place and, as far as I can tell, with the correct permissions to be referenced by the x509Certificate2 class:

The name of the key file matches to the Subject Key Identifier on the certificate.


The output of certutil -user -store my "Serial Number" is:

What “key” piece of information am I missing here? Why isn’t the private key conveniently referenced from the X509Certificate2 object? How do I gain access to it?


This may indicate one of the following:

1) the private key is stored in the Key Storage Provider (rather than legacy crypto service provider) which is poorly supported by .NET and not supported by PrivateKey property of X509Certificate2 class at all. You can check this by running the following command:

2) the private key is missing.

HasPrivateKey property doesn’t necessary reflect the actual picture and may True for non-existent keys or False for existing keys. Run the certutil command above to make sure if the key is presented.

In the case if private key is presented, but the bindings are broken, you can try to restore bindings by running the following command:


.NET Framework x509Certificate2 Class, HasPrivateKey == true && PrivateKey == null? by licensed under CC BY-SA | With most appropriate answer!

Leave a Reply