Transport Layer Security (TLS) is a protocol for encrypting data being sent from one machine to another. It is the successor of the Secure Sockets Layer (SSL), and is now the encryption standard used by most modern web browsers. Initially, the client verifies the server’s TLS certificate with the certificate authority that issued it. Then the initial handshake between the client and the server involves verifying the asymmetric key pair (public/private keys), before exchanging symmetric session keys that will be used for encryption and decryption for the remainder of the session.
When you first start working with TLS certificates hands-on, it may be challenging to know where to start and how things work together. This blog post aims to go through all the necessary steps from start to finish for how to request and install TLS certificates, and will do so in the simplest manner possible.
A prerequisite for this guide is to have OpenSSL installed.
1 Generate CSR and private key
A CSR (Certificate Signing Request) is a block of encoded text that is provided to a Certificate Authority when applying for an TLS Certificate. It is usually generated on the server where the certificate will be installed and contains information that will be included in the certificate such as the organization name, common name (domain name), locality, and country. It also contains the public key that will be included in the certificate. A private key is generated at the same time as when the CSR is created, and act as a key pair with the public key.
This step should should always be performed even if you do not have to make any changes to the CSR file (if you want your certificate to remain the same.) This is because this step will generate a new private key, and renewing keys is a good security step — just like users periodically being forced to change their passwords.
1.1 Create a CSR config file that will be used to generate the CSR and private key from
Config files makes it easier to regenerate CSR files at any given time. An example of such a config file could look like this (file name example: myapp.mydoman.com.cnf):
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[ req_distinguished_name ]
countryName = NO
stateOrProvinceName = Oslo
localityName = Oslo
organizationName = My Company
organizationalUnitName = Some Unit
commonName = myapp.mydomain.com
[ req_ext ]
subjectAltName = @alt_names
DNS.1 = myapp.mydomain.com
DNS.2 = myapp-dev.mydomain.com
DNS.3 = myapp-test.mydomain.com
1.2 Open a a terminal window and change directory to where you want the private key and CSR file to be generated
This will typically be in a folder of your version control repository that will contain the certificate-related files.
1.3 Generate a password for the private key to be generated
This should be a strong password, preferably minimum 15 characters long, with lowercase and uppercase letters, numbers, and special characters.
1.4 Generate CSR and private key from the CSR config file
Execute the following command:
openssl req -new -newkey rsa:2048 -out myapp.domain.com.csr -keyout myapp.domain.com_encrypted.key -config myapp.domain.com.cnf
The generated private key should preferably not be pushed to version control, and should be ignored in the repository (i.e. via gitignore). The private key should be stored separately from the certificate in a safe place.
TIP: If you ever come across a non-encrypted private key, then it can be encrypted by using this command (you will be prompted for the password it should be protected with after executing command):
openssl rsa -des3 -in myapp.domain.com.key -out myapp.domain.com_encrypted.key
1.5 Decrypt the private key to ensure that the password you entered was correct
openssl rsa -in myapp.domain.com_encrypted.key -out myapp.domain.com.key
After you have verified that the password works for decrypting the key, delete the decrypted key file from the machine entirely.
1.6 Decode and view CSR as plain text
If you want to view the CSR as plain text, then you can decode it with the following command:
openssl req -in myapp.domain.com.csr -noout -text
2 Provide the CSR to a certificate authority
Provide the CSR file to a certificate authority, so that they can generate and issue a certificate to you.
3 Process and renew the issued certificates
A certificate authority may issue the certificate in several different formats. They can send it as a composite certificate, containing the Server, Intermediate and Root certificates combined, or they may send them as separate files.
I find it easiest to have the certificates in one .crt file. To do this, simply add the certificates in a new .crt file from top to bottom:
The newly created .crt file will be the certificate that should eventually be deployed on your server. Verify the contents of the .crt file by executing the following command:
openssl x509 -in myapp.domain.com.crt -text -noout
Pay attention to the contents, such as the common name, SANs etc. — they should match what is in your CSR file.
Before deployment, we need to decrypt our encrypted private key (see section 1.5).
Check if the certificate indeed matches the private key by executing the following commands:
openssl x509 -noout -modulus -in myapp.mydomain.com.crt | openssl md5openssl rsa -noout -modulus -in myapp.mydomain.com.key | openssl md5
You should get an output for each of these commands which starts with “(stdin)=”. If the hash values on the right side of the equal operator are equal when running both commands, then the private key matches the certificate.
If your server has built in functionality for deploying both the certificate and the private key in one bundle, then it may prefer the .pfx format, which holds both the certificate and private key in one file.
To do this, you can run the following command:
openssl pkcs12 -export -in myapp.mydomain.com.crt -inkey myapp.mydomain.com.key -out myapp.mydomain.com.pfx
If not, then the server is likely interested in in the .crt and .key file separately — in one or two different locations on the server.
4 Deploy the certificate and private key to the server
Follow the documentation of your server on how to deploy the certificate and private key to the server.
After deployment, you can verify the deployed certificate with the following command:
openssl s_client -connect <your_server_ip>:443 -showcerts
You can also verify the certificate on Entrust SSL Labs.