I'm trying to implement a secure TCP server and as the result I need to create an object of class X509Certificate2
in order to authenticate the clients.
I believe such a certificate object should contain the private key (as well) in order to be able to decrypt incoming messages, isn't that true? Well no matter how I generate a certificate file, when I give its file address to X509Certificate2
's constructor the object's HasPrivateKey
property is false and clients are not authenticated!
In the Microsoft's page on how to use the X509Certificate2
class, in source code's comments it indicates that the certificate can be generated using makecert
program like this:
makecert -r -pe -n "CN=CERT_SIGN_TEST_CERT" -b 01/01/2010 -e 01/01/2012 -sky exchange -ss my
In which -pe
switch should include the private key in certificate but looking at the generated file I can tell that it does not do that.
Since I'm implementing this software in Ubuntu using Mono I thought I can use openssl
instead. So following the instructions given in this page I created a private key and a public key. X509Certificate2
class accepts the public key as if it was created by makecert
command but not the private key (it throws an exception when it is constructed).
There is a relatively old post in SO which asks the same question but it has no accepted answer. And the two given ones suggest using two different formats for certificates, PKCS8 and PKCS12 while in the documentation it is clearly said that X509Certificate
make use of PKCS7!
Anyway I'm all confused. Has anyone ever been able to use X509Certificate2
with a private key loaded? How?
An X509 certificate should only contain a public key. It binds the public key to an identity and is signed. RFC 5280 contains the details on X509 certificates.
However, the
X509Certificate2
object can contain a private key according to the MSDN documentation.Also, a keystore, such as a PKCS12 keystore can contain a private key and a corresponding certificate.
PKCS7 is a specification for signing and encrypting messages.
PKCS8 is a specification for private keys.
See PKCS for the differences between different PKCS standards.
The MSDN link above has some example C# code to encrypt and decrypt files. It also has an example
makecert
command line to generate a certificate. However this certificate and associated private key is stored in the Windows local user store, so I'm not sure if that will translate correctly to Ubuntu.There is also some discussion in this SO question about using PKCS12 keystores to instantiate the
X509Certificate2
object and then to access the private key. This might be the better way for you to accomplish your goal. You can use openssl to generate a private key, a signed certificate, and import them into a PKCS12 keystore. You can create a PKCS12 keystore using the commands here. For example, create a text file (file.pem) containing both the PEM format of your private key and corresponding X509 certificate. Then run this command:Also on the
makecert
documentation page, it says, "for testing purposes only". So I wouldn't depend on those certificates for a production secure server.