4

I am attempting to create a TCP connection on TLS encryption in C#, using an OpenSSL generated cert.

The SslStream sample code given here seems to work using a cert created with windows makecert.exe, which comes out as a .cer file. It does not work with a cert created through OpenSSL, which is a .pem file, throwing excpetion: "The server mode SSL must use a certificate with the associated private key."

Both cert files are being parsed successfully into X509Certificate objects as I can see their issuers and subjects and other properties, and note that the "HasPrivateKey" property is false "PrivateKey" property is null on both of them.

I found this which says that you need to combine the (OpenSSL) certificate and private key into one PKCS12 package. Yet a PKCS12 package is the file format .pfx -- why does an OpenSSL cert have to be combined with a private key into a pfx, but a makecert-generated .cer file does not need to be a pfx (and is not PKCS12)?

Also, what is different about the OpenSSL certificate in the first place that makes it throw this exception about a missing private key, when the MakeCert certificate also does not have a private key? Or to put another way, why does the MakeCert certificate not seem to require a private key, like the OpenSSL cert?

user1169420
  • 680
  • 7
  • 18

1 Answers1

1

Someone on IRC suggested to me that it might be that makecert is putting credentials in the windows Certificate Store. I didn't expect that would be the case since we are exporting files, but I moved my SslStream prototype (with makecert certificates) to a different machine (ie not the one where makecert was run) and I got the same error "The server mode SSL must use a certificate with the associated private key."

So officially, the answer is "makecert puts the key into your cert store, and when you run AuthenticateAsClient, in the background it is pulling the private key out of there. This is why the makecert certificate works and the OpenSSL cert doesn't, even though they are almost identical.

Taking it a step further, to get the thing working with OpenSSL certs, I'm sure the advice I linked in the question about combining the public and private keys into a PKCS12 (.pfx) file would have worked, however I wanted to load/combine them on the fly. I found this codeproject article which contains sample code that does all the dirty work of decoding the RSA private key, making it into an RSACryptoProvider, and attaching that object to the X509Certificate2.PrivateKey property. After doing this and providing paths to the seperate cert and private key files generated by OpenSSL, everything works great!

user1169420
  • 680
  • 7
  • 18
  • Update: The code in that codeproject article at current time does not support the old obsolete Windows Server 2003. Keep this in mind if it affects you. – user1169420 Jun 02 '15 at 17:50