Create your own SSL certificate factory

Create and signed SSL certificates with your own Certificate Authority (CA)
created by on 2013-07-01

Terminology

File Extensions

Certificate file formats

SSL certificates can be stored in different formats.

PEM Format

The PEM format is the most common format that Certificate Authorities issue certificates in.
PEM certificates usually have extentions such as .pem, .crt, .cer, and .key.

They are Base64 encoded ASCII files and contain “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–” statements.
Server certificates, intermediate certificates, and private keys can all be put into the PEM format.

DER Format

The DER format is simply a binary form of a certificate instead of the ASCII PEM format.
It sometimes has a file extension of .der but it often has a file extension of .cer so the only way to tell the difference between a DER .cer file and a PEM .cer file is to open it in a text editor and look for the BEGIN/END statements.

All types of certificates and private keys can be encoded in DER format.

PKCS#7/P7B Format

The PKCS#7 or P7B format is usually stored in Base64 ASCII format and has a file extention of .p7b or .p7c.
P7B certificates contain “—–BEGIN PKCS7—–” and “—–END PKCS7—–” statements.

A P7B file only contains certificates and chain certificates, not the private key.

PKCS#12/PFX Format

The PKCS#12 or PFX format is a binary format for storing the server certificate, any intermediate certificates, and the private key in one encryptable file.
PFX files usually have extensions such as .pfx and .p12.

Steps

Creating an ssl-factory from scratch consists of seven steps:

  1. Create the directories for the SSL certificate factory
  2. Create an openssl configuration
  3. Adapt the openssl configuration
  4. Create a Certificate Authority (CA) certificate
  5. Create a certificate request
  6. Creata a certificate extension for the certificate request
  7. Sign the certificate request

Once you have completed the process you will not need to repeat the steps 1 to 4 if you want to create a new certificate.

1. Create the directories for the SSL certificate factory

Create a directory in your home-directory ~/ssl-factory which will hold your CA certs, CSR files, private keys and certificates:

mkdir -p -m 0755 \
	~/ssl-factory/myCA \
	~/ssl-factory/myCA/private \
	~/ssl-factory/myCA/certs \
	~/ssl-factory/myCA/newcerts \
	~/ssl-factory/myCA/crl

Screenshot: Create directory structure for the SSL-factor

Folder Descriptions

2. Create an openssl configuration

Copy the openssl configuration file of your operating system into your newly created ssl-factory directory:

cp /etc/ssl/openssl.cnf ~/ssl-factory/myCA/openssl.cnf

Reduce the visibility of the configuration file:

chmod 0600 ~/ssl-factory/myCA/openssl.cnf

Create an index file which will be used to keep track of the certificate signing requests:

touch ~/ssl-factory/myCA/index.txt

Initialize the serial number seed for your CSR requests:

echo '01' > ~/ssl-factory/myCA/serial

Screenshot: Preparing the openssl configuration

If everything worked your ssl-factory folder ~/ssl-factory/myCA should look something like this:

Screenshot: Folder and files of the ssl-factory before the first use

3. Adapt the openssl configuration

The openssl configuration of your OS should be good to go, but you will need to change the base path to the location of your ssl-factory.

Open your openssl configuration ~/ssl-factory/myCA/openssl.cnf in an editor of your choice and change
- the dir variable to .
- the certs variable to dir/certs
- the database variable to $dir/index.txt
- the certificate variable to $dir/certs/cacert.crt
- the serial variable to $dir/serial
- the private_key variable to $dir/private/cakey.key

...
[ CA_default ]
dir                 = .                         # Where everything is kept
certs               = $dir/certs                # Where the issued certs are kept
crl_dir             = $dir/crl                  # Where the issued crl are kept
database            = $dir/index.txt            # database index file.
# unique_subject     = no                        # Set to 'no' to allow creation of several certificates with same subject.
new_certs_dir       = $dir/newcerts             # default place for new certs.
certificate         = $dir/certs/cacert.crt     # The CA certificate
serial              = $dir/serial               # The current serial number
crlnumber           = $dir/crlnumber            # the current crl number must be commented out to leave a V1 CRL
crl                 = $dir/crl.pem              # The current CRL
private_key         = $dir/private/cakey.key    # The private key
RANDFILE            = $dir/private/.rand        # private random number file
x509_extensions     = usr_cert                  # The extentions to add to the cert
...

Screenshot: Change the CA_defaults of your openssl configuration

And you might want to increase the default number of days before an certificate expires from 365 days (1 year) to something little more convenient (e.g. 10 years):

...
default_days        = 3650          # how long to certify for
default_crl_days    = 30            # how long before next CRL
default_md          = default       # use public key default MD
preserve            = no            # keep passed DN ordering
...

Screenshot: Change the default_days variable of your openssl configuration to 10 years

As well as the default key strength in the req section:

...
[ req ]
default_bits        = 2048
...

4. Create a Certificate Authority (CA) certificate

Now you can switch into your myCA folder of your ssl-factory and create your Certificate Authority certificate and key:

cd ~/ssl-factory/myCA
openssl req -config openssl.cnf -new -x509 -extensions v3_ca -keyout private/cakey.key -out certs/cacert.crt -days 3650

You will be asked to enter:

Screenshot: Creating the Certificate Authority certificate and key

Once you have enter all required information openssl will create two new files in your folder structure:

  1. private/cakey.key
  2. certs/cacert.crt
~/ssl-factory
└── myCA
    ├── certs
    │   └── cacert.crt
    ├── crl
    ├── index.txt
    ├── newcerts
    ├── openssl.cnf
    ├── private
    │   └── cakey.key
    └── serial

5 directories, 5 files

Screenshot of the private key for the newly created CA certificate

Screenshot of the CA certificate

Now that you have a CA certificate you can create and sign as many SSL certificates with it as you like.

5. Create a certificate request

… which can then be signed by your new CA certificate. Go into the factory directory ~/ssl-factory/myCA and create a new certificate request named cert1.csr:

cd ~/ssl-factory/myCA
openssl req -config openssl.cnf -new -nodes -keyout private/cert1.key -out cert1.csr -days 3650

You will be asked to enter meta data for your certificate:
- Country Code: DE
- State: NRW
- City: Some City
- Organization Name: Some Organization
- Common Name of your certificate: server1.example.com
- Email Address: [email protected]
- A challenge password: –just hit <enter> here–

Screenshot: Creating a first certificate signing request

6. Creata a certificate extension for the certificate request

If you want to add one or more DNS names to your certificate request you must create a certificate extension file:

cd ~/ssl-factory/myCA
vi cert1_extensions.txt
[ cert1_http ]
nsCertType = server
keyUsage = digitalSignature,nonRepudiation,keyEncipherment
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName = @cert1_http_subject

[ cert1_http_subject ]
DNS.1 = server1.example.com
DNS.2 = server1-assets.example.com
DNS.3 = server1-services.example.com

For example the above extension file will allow you to use the certificate not only for the main domain (server1.example.com), but also for other domains such as:
- server1-assets.example.com
- server1-services.example.com

Screenshot: Create an extension file for your certificate request

7. Sign the certificate request

Now you have everything in place to sign your certificate request with your own CA certificate:

cd ~/ssl-factory/myCA
openssl ca -policy policy_anything -config openssl.cnf -in cert1.csr -extfile cert1_extensions.txt -extensions cert1_http -out certs/cert1.crt

When asked for password enter the password you used for your CA certificate.

Screenshot: Signing the certificate request with the CA certificate and the supplied certificate extension

When everything went ok you will have two new files in your ssl-factory folder:

  1. certs/cert1.crt (This is the server’s certificate, which can be made available publicly)
  2. newcerts/01.pem (This is exactly the same certificate, but with the certificate’s serial number as a filename. It is not needed)

Screenshot: The files and folders of the ssl-factory after the certificate request has been signed by the CA

Summary

The above steps will result into two new SSL certicates:

  1. A Certificate Authority (CA) certificate which can be used to sign certificate requests (certs/cacert.crt)
  2. A signed certificate for a server which is valid for three different domains (certs/cert1.crt)

Screenshot: The newly created CA certificate and the signed certificate request

Files

Below you will find the openssl configuration file used in this tutorial and a backup of the ss-factory folders before and after creating certificates with it:

Related Links

Credits

This document has been largely inspired by this article:
G-Loaded Journal - Be your own Certificate Authority (CA)

Tags:
Fork allmark on GitHub