Wednesday, August 22, 2012

[Tutorial] How to generate certificate authority and server certificates using OpenSSL


Many people struggle when they first have to generate correct certificates to work with ssl libraries. There are many tools out there and a number of different file formats and things can get confusing quickly. This tutorial will help you generate your own certificate authority and server certificates to be used for your secure server/client.

Generating Certificate Authority

Certificate Authority is a trusted third party that vouches for servers a client is trying to talk to.
We will be setting up our own CA for our application. This can be useful if you are just looking to test your server or your server will not be accessible by the public.

 openssl req -new -x509 -keyout ca-key.pem -out ca-cert.pem -days 365  

Enter appropriate passphrase when prompted.
This will generate two files:
ca-key.pem - certificate authority private key
ca-cert.pem - certificate authority public certificate

Notice that this CA certificate will only be valid for 365 days.

Generating Server Certificate

Now we need to generate server private key and certificate signing request.
Certificate signing request file is later sent to certificate authority to be signed and generate server public certificate. During SSL handshake, the server sends this signed public certificate to the client and the client can verify it with CA public certificate to make sure the server is trustworthy.

 openssl genrsa -aes128 -out server-key.pem 4096

Set appropriate passphrase for server private key when prompted.
This command will generate RSA server private key of size 4096 bits using 128bit AES algorithm.
Generally key size of 2048 or higher is recommended.

 openssl req -new -key server-key.pem -out server.csr

This command will generate server certificate signing request file. This file is later sent to certificate authority (in this case, our own) to be signed to generate signed public certificate for the server.

Signing Server Certificate with our own Certificate Authority

Once server certificate signing request file is generated, we can send it to well known certificate authority like GoDaddy to be signed but usually there is a fee associated with it.
In our case, we will be signing the certificate signing request file with our own certificate authority generated earlier.

 openssl x509 -req -days 365 -in server.csr -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

This will generate server-cert.pem signed by our own certificate authority and ready to be used!

Removing the Passphrase from Server Private Certificate

Server private key is protected by a passphrase. The private key is to be never shared with anyone else. However if adversary somehow get his or her hands on the private key then this passphrase will protect the file. It is very unlikely that this will happen and also we need to enter the passphrase everytime we run our server and this can get somewhat annoying. Also our cyassl example will fail to load the key with error code NO_PASSWORD if passphrase isn't provided.
As a simple solution, we will simply remove the passphrase from the server private key.

 openssl rsa -in server-key.pem -out server-key-nopass.pem

This command will generate password-free server private key, server-key-nopass.pem.

Generating Java Keystore and Importing CA certificate

In case you are using Java server, you need to generate a keystore where CA certificates are stored.
This can be generated using "keytool" included in Java package.

 keytool -genkey -keyalg RSA -keystore keystore.jks -keysize 4096

This will generate keystore.jks. Now that you have a keystore, we need to import our ca-certificate generated earlier.

 keytool -import -trustcacerts -alias MyCA -file ca-cert.pem -keystore keystore.jks

Testing Generated Certificates

You can install generated certificates using CyaSSL.
Download CyaSSL tutorial code from their website.

Under finished_src directory, you will notice echoclient and echoserver directories.
We need to copy our own generated certificates to echoclient and echoserver directories.
cp ca-cert.pem /ssl-tutorial-2.0/finished_src/echoclient/.

 cp ca-cert.pem ./ssl-tutorial-2.0/finished_src/echoclient/.
 cp ca-cert.pem ./ssl-tutorial-2.0/finished_src/echoserver/.
 cp server-key-nopass.pem ./ssl-tutorial-2.0/finished_src/echoserver/server-key.pem
 cp server-cert.pem ./ssl-tutorial-2.0/finished_src/echoserver/.

Now compile and run the echoserver and echoclient and see if it works!

Please let me know if there are any mistakes.
I would also appreciate if someone can tell me how to load password-protected server private key.