Import certificate with private key programmatically

12,981

Ok, I figured it out. It had to do with the key storage parameters for the certificate object. For anyone else that runs into this problem, make sure you construct your X509Certificate2 objects that you are adding to the store using the X509KeyStorageFlags.PersistKeySet and X509KeyStorageFlags.MachineKeySet flags. This will force the private key to persist in the machine key set location which is required by HttpApi (HttpListener wraps this).

Share:
12,981
Jason
Author by

Jason

Updated on June 05, 2022

Comments

  • Jason
    Jason almost 2 years

    I'm trying to use the HttpListener class in a C# application to have a mini webserver serve content over SSL. In order to do this I need to use the httpcfg tool. I have a .pfx file with my public and private key pair. If I import this key pair manually using mmc into the local machine store, everything works fine. However, if I import this key pair programmatically using the X509Store class, I am not able to connect to my mini webserver. Note that in both methods the cert is getting imported to the MY store in LocalMachine. Oddly, I am able to view the certificate in mmc once I programmatically import it and when I view it, the UI indicates that a private key is also available for this certificate.

    Digging a little deeper, I notice that when I manually import the key pair, I can see a new file appear in C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys, but one does not appear when I import programmatically. On a related note, when I delete a manually imported certificate, it does not remove the corresponding private key file from the previously mentioned directory.

    Ultimately, my question is this: When I programmatically add the certificate to the store, where is the private key being stored and why isn't it accessible to the HttpListener class (HttpApi)?

    Note that this question is slightly related but I don't think permissioning is the problem since this is all being done as the same Windows user: How to set read permission on the private key file of X.509 certificate from .NET

  • Jason
    Jason almost 15 years
    I am just using a self generated key pair for testing at the moment so there is this cert request involved. I haven't played with anything permissions related yet since all of this is being done as the same user (cert import and running the webserver). There is no IIS or anything else involved.
  • Jason
    Jason almost 15 years
    Unfortunately I have to wait 48 hours before I can do so at which point I will likely forget to do it. :(
  • Jason
    Jason almost 15 years
    Thanks, that's a good link. I briefly looked into that, but it only goes into how to use the URLACL_SET struct and not the SSL_SET one which is needed for managing the SSL configuration in my scenario. Unfortunately the SSL_SET struct is quite a bit more complex so it simply became to cumbersome to work with and the httpcfg executable was more convenient.
  • Brett Widmeier
    Brett Widmeier about 14 years
    I wasted about 30 minutes trying to figure why "X509KeyStorageFlags.MachineKeySet & X509KeyStorageFlags.PersistKeySet" wasn't working. Of course, it should be "X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet." Fairly obvious, just in case someone else tries the same stupid thing that I did.
  • dgvid
    dgvid about 13 years
    There is a small amount of sample code at: support.microsoft.com/kb/950090
  • Yannis
    Yannis over 4 years
    @Jason you wont believe how much time you saved me. I was already in my 2nd day of research and the whole internet was a giant dead-end. Thank you!