Generate X509 Certificate Private Key

We're trying to generate an X509 certificate (including the private key) programmatically using C# and the BouncyCastle library. We've tried using some of the code from this sample by Felix Kollmann but the private key part of the certificate returns null.

How To Create X509 Cert

Freelan relies on X509 certification for its authentication mechanism. For several hosts to connect using freelan, each and everyone of them will have to have his unique certificate.

You can use this Certificate Key Matcher to check whether a private key matches a certificate or whether a certificate matches a certificate signing request (CSR). When you are dealing with lots of different certificates it can be easy to lose track of which certificate goes with which private key or which CSR was used to generate which certificate. Any X509 certificate can be signed by another certificate called a parent certificate. This signature is generated with the private key associated with the parent certificate and guarantees that the signed certificate was verified by the people that own the parent certificate (also called a certificate authority ).

Certificate generation is a very sensitive topic that must not be taken lightly, and I encourage you to read a lot about it and to fully understand its principles before you continue.

To generate certificates, you will need the openssl command line tool. Make sure it is in your PATH so that you can execute it from anywhere.

How To Generate X509 Public Key Certificate

A freelan host (also called 'contact') identifies himself by presenting a X509 certificate to other hosts. This certificate is public. One can give it to anyone without facing security issues.

This certificate contains a public RSA key which anyone can read and use and, amongst other things, a common name which can be anything from an email address to a hostname: this common name identifies the host and should be unique inside the virtual private network.

Associated with this certificate is a private key. As its name implies, the private key is private and MUST remain so ! I cannot stress that enough: Never give your private key to anyone ! Don't store it on your desktop. Don't send it in cleartext to your email account. Don't make a t-shirt out of it.

If you are curious about why we need those two elements, here is a short explanation:

Certificate
  • If someone uses the public key to cipher something, only the owner of the private key can decipher it. That is, you have the guarantee that when a message is sent, only the intended recipient can read it.
  • If someone uses its private key to 'cipher' (actually, 'sign') something, anybody with the associated public key can read it. That is, you have the guarantee that when a message is received, its emitter is really who he claims to be and that the message was not altered during the transmission.

Those two principles are sufficient to ensure both authenticity and confidentiality but have a cost: you have to generate the private keys and the certificates first.

While certificates give us authenticity and confidentiality, anyone can generate a certificate containing wrong information (an incorrect 'common name' for instance) and so we have to check every certificate we were given, and to ensure that they really were emitted by the people or the organization they refer to. Those verifications are really time consuming.

Luckily enough, X509 contains a mechanism to ease this which is called certificate signing.

Any X509 certificate can be signed by another certificate called a parent certificate. This signature is generated with the private key associated with the parent certificate and guarantees that the signed certificate was verified by the people that own the parent certificate (also called a certificate authority).

X509

That is, with this mechanism, one doesn't have to trust directly every possible certificate, but only the parent certificates. It is worth saying that this makes the parent private keys even more sensitive !

Note: The parent certificate can also be signed by an even higher parent certificate. This is often referred to as a certificate chain.

Good ? Let's create certificates !

Here are the steps to create a simple certificate authority.

Get the certificate authority sample folder archive and extract it where you like.

Go inside the extracted folder and type:

When prompted for a passphrase, type what you want, but remember it ! You will have to type it whenever the certificate authority private key file will be needed.

You should now have a certificate file at crt/ca.crt and its associated private key file at key/ca.key.

Now that you have a working certificate authority, it is time to generate client certificates. Repeat the following step for every certificate/private key pair you need.

Private key generation

The first step is to generate a private key:

If you wish to protect your private key with a passphrase, use the following command line instead:

Note: Using a passphrase will increase the security of your private key. Even if it gets stolen, the password will be required to use the private key. However, setting a passphrase on the private key can prevent its use in automated systems.

This will generate a file named alice.key. This is the client private key.

Note: every host should generate its own private key to keep it secret. The certificate authority does not need the client private key to sign the client certificate.

Issuing a certificate request

Now that a client has a private key, it must generate a certificate request out of it. This certificate request will be 'send' to the certificate authority which can then chose to accept it and generate a signed certificate from it.

To generate a certificate request, type the following command:

Fill all the certificate request attributes.

This will generate a file named alice.csr. This is the client certificate request.

Note: Those two steps (private key and certificate request generation) do NOT need to be done in the certificate authority folder. Actually, they should even be done on the final host directly for privacy's sake.

Generating a signed certificate from a certificate request

The final step is to generated a signed certificate from the certificate request. This is obviously done on the CA.

Type the following command:

This will prompt for the ca.key passphrase then ask you whether you want to accept the certificate request.

Generate X509 Certificate Private Key Export

This will generate a alice.crt file: the client signed certificate which can be send to anyone.

Openssl

Repeat these steps for every client, and you will be ready to use freelan ! Congratulations !