Friday, July 17, 2020

Creating your own CA and development certificates

Into the world of SSL/TLS we go again.

For this I will need my own CA. I seem to always set one up but forget the process I followed so I’m documenting it here now. Hopefully you can benefit from this.

Step 1 - Create your private key
First we need to create our private key with the following command:

  • openssl genrsa -aes256 -out myCA.key 2048

The above step will produce a file called myCA.key which is your private key for the CA. Make sure you don’t lose this or the passphrase you provided to generate the key. Normally I suspect this key would be kept in an HSM device.

Step 2 - Create your certificate
Now we will generate the root certificate using this command using the key file we just created, you will need to enter the passphrase you used in step 1.
  • openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem

Make sure you are careful when you input the values as the input does not support backspace, so if you stuff up something rather run this step again.

You can check out the cert details by running the following command:
  • openssl x509 -in myCA.pem -text -noout

This should show like below, make sure you double check the subject of the certificate that it matches the values you inputted:

Now you have completed this step you can import the certificate into your trusted root store so that that any certificates you sign/create will be trusted.

Get the certificate on you PC and install. On windows it’s easiest to rename the certificate .pem file to .cert like so:

Right click on and chose install 'Install Certificate'
Make sure you add it to your trusted root certificates:

Step 3 - Creating you development server certificates
Now that we have a CA we can sign certificates :-) :-)

Follow this process to create and sign a certificate.

  1. Create a private key with the following command:
  • openssl genrsa -out dev.myserver.key 2048
  1. Ok this is where it gets tricky! You use the following command to create a certificate signing request (CSR) using the private key you created in the previous step:
  • openssl req -new -key dev.myserver.key -out dev.myserver.csr
BUT WAIT! you more than likely want to have multiple names of the dev server that you would reference by DNS/IP e.g. I have the following for my dev server:
  • mypingaccess

In order to add these alternative names, also known as subject alternative names (SANs) you need to do the following:

b1) create a configuration file that contains the the names like so:

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext
prompt = no
[ req_distinguished_name ]
countryName                = ZA
stateOrProvinceName        = Gauteng
localityName               = Sandton
organizationName           = IT
commonName                 =
[ req_ext ]
subjectAltName = @alt_names
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
[ alt_names ]
DNS.1   = mypingaccess
DNS.2   =
DNS.3   =

I created the file in /tmp/san.cnf

b2) then I ran the following command to create the CSR: 
  • openssl req -out dev.myserver.csr -newkey rsa:2048 -nodes -keyout dev.myserver.private.key -config /tmp/san.cnf
b3) now make sure the SANs are part of the CSR with the following command:
  • openssl req -noout -text -in dev.myserver.csr | grep DNS
You should see the following output:

  1. Now that we have a CSR we can sign it with our CA. Use the following command to sign it:
  • openssl x509 -req -in dev.myserver.csr -CA myCA.pem -CAkey myCA.key -CAcreateserial -out dev.myserver.crt -days 825 -sha256 -extfile /tmp/san.cnf -extensions req_ext
  1. Now check that the SANs are in the newly signed cert with the following command:
  • openssl x509 -in dev.myserver.crt -text -noout | grep DNS
You should have the following:

This part really broke a number of times by following a number of online posts because they did not include the -extfile and -extensions option, also when they did include it they reference another cnf file and not the one I used to create the CSR. What I also found was that if this file had the incorrect parameters in it that the DNS SANs name would be stripped (not included) in the certificate (the CRT file).

Cool now that we have the certificate we need to install it on our server. This will depend on the application/web server you are using, but please keep in mind that because the server is encrypting the content it will need both the private and public keys.

Some application servers like Apache will allow you to provide both the private and public keys separately, while other servers will require a keypair. Here are the steps to create a PKCS#12 keypair:

  • openssl pkcs12 -export -out certificate.pfx -inkey dev.myserver.private.key -in dev.myserver.crt

This will prompt you for a password to protect the keypair because it contains the private key which you should not share with a public entity. You should now have a certificate.pfx file you can import as required.

Here’s an example of how I imported this in PingAccess:

1) Go to the Security -> Key Pairs option and click 'Import'

2) Provide an alias for the key pair, provide the password and upload the 'certificate.pfx'

3) Click ‘Save’ on the bottom right. You should get the following pop up->

4) View the key pair:

If you connect to PingAccess you will still get a certificate error as you now need to configure the HTTP listener to use the key pair.

You will see that the current ADMIN key pair was created on installation and is set as the ADMIN HTTPS listener:

Now go back to the key pair list and click the pencil icon on the key pair you imported. From the drop down select the 'Assign HTTPS Listener' option:

Choose where you want to use the key pair:

The good news is no restart required. Open another browser instance or incognito mode and you connection should be secure:

You can view the certificate and confirm the path: