c# X509Certificate2 add certificate how mark as exportable

4

I have a .NET 4.0 program which is running localhost on port 9000. I want to support SSL and have a .pfx certificate to import.

Because the program is running at multiple computers the programm itself is responsible to store the certificate and register the its port.

When imported and registered by the program, everything works. But when I reboot the computer the https connection does not work any.. more..

The event viewer gives the following error:

A fatal error occurred when attempting to access the SSL server credential private key. The error code returned from the cryptographic module is 0x8009030D. The internal error state is 10001.

and

An error occurred while using SSL configuration for endpoint 0.0.0.0:9000. The error status code is contained within the returned data.

I found some solutions which state that you need to mark the certificate as 'exportable' while importing but I can't find how I do that in code.

Website 1 and Website 2

Storing the certificate:

String path = String.Concat(IOHelper.AssemblyPath, @"\certificate.pfx");
X509Certificate2 cert = new X509Certificate2(path, "password");

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);

if(!store.Certificates.Contains(cert))
{
    store.Add(cert);
}

Registering the host:

netsh http add sslcert ipport=0.0.0.0:9000 certhash=<cert hash> appid=<app id>
c#
ssl
localhost
x509certificate
netsh
asked on Stack Overflow Jun 23, 2014 by Justin

2 Answers

4

To mark a X509Certificate2 as exportable is actually quite simple. You add a third parameter (X509KeyStorageFlags.Exportable) which indicates that the certificate is exportable.

var cert = new X509Certificate2(path, "password", X509KeyStorageFlags.Exportable);
answered on Stack Overflow May 21, 2015 by Ebbelink • edited Feb 7, 2019 by Stefan
2

Further to Madeillei's answer, you can pass the following flags:

var cert = new X509Certificate2(path, "password", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable| X509KeyStorageFlags.MachineKeySet);

If you are storing the cert in the CurrentUser store rather than in the LocalMachine store, do the following:

var cert = new X509Certificate2(path, "password", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable| X509KeyStorageFlags.UserKeySet);

The Key set flags indicate the following:

    //
    // Summary:
    //     Private keys are stored in the current user store rather than the local computer
    //     store. This occurs even if the certificate specifies that the keys should go
    //     in the local computer store.
    UserKeySet = 1,
    //
    // Summary:
    //     Private keys are stored in the local computer store rather than the current user
    //     store.
    MachineKeySet = 2,

The private key needs to be in the same place as the rest of the certificate for it to work.

answered on Stack Overflow Aug 5, 2019 by Roberto Bonini

User contributions licensed under CC BY-SA 3.0