Categories
Public Key Infrastructure

How to Create a Certificate

October 2020 – written by dogoncouch and edited by leaena.

Concept

Certificates are an important part of trust on the internet. They make it possible to verify the identity of a system when connecting to it, and they provide the basis for encrypted communication. For an overview of certificates and public key infrastructure, see my article on how certificates work.

Goal

The goal is to create a few certificates. We’ll start off by creating a certificate signing request, which could be sent to a certificate authority for signing. Then we’ll look at how to add a certificate chain to the resulting certificate, and how to convert it to PKCS #12 format. Finally, we’ll create a self-signed certificate. Self-signed certificates are less secure, but it is still possible to connect to a system that has a self-signed certificate in a secure way by verifying the certificate. For more on verifying certificates, see my article on how to verify a certificate.

Tools

OpenSSL is an open-source suite of tools for working with certificates, centered around the command line program openssl. Secure sockets layer (SSL) is the name for the original standard for securing web traffic, created by Netscape in the 1990s. The modern standard is transport layer security (TLS), but SSL is often used as a blanket term to refer to both. We will be using openssl to work with certificate signing requests (CSRs) and certificates; this can be done on either Linux or Mac OS.

Process

CA-Signed Certificate

Certificate Signing Request

Creating a CSR with openssl is fairly simple. Before starting, make sure to have the following information about the server or entity that the certificate will be issued to. Other than Common Name, most attributes aren’t strictly required, but it’s a good idea to fill them in to help identify the server.

  • Country (two-letter country code)
  • State/Province (spelled out in full)
  • Locality (e.g. city or town; this could be where the server is, or where your company is based/where you live)
  • Organization (this is often the company that owns the server)
  • Organizational Unit (the department within the organization)
  • Common Name (the server’s DNS name, e.g. netlab.dogoncouch.net)
  • Email address

Now, let’s create the CSR. Command line options will be explained below.

dogoncouch@localhost:~$ openssl req -new -out myserver.csr -newkey rsa:2048 -keyout myserver.key -sha256
Generating a 2048 bit RSA private key
.........................................................................+++
............................................................................................................+++
writing new private key to 'myserver.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:US
State or Province Name (full name) []:New Jersey
Locality Name (eg, city) []:Jersey City
Organization Name (eg, company) []:dogoncouch.net
Organizational Unit Name (eg, section) []:NetLab
Common Name (eg, fully qualified host name) []:myserver.dogoncouch.net
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:

That will create two files in the current directory: myserver.csr, the CSR, and myserver.key, the key. Let’s review the command line options. openssl has a number of sub-commands, and openssl req is the one that deals with CSRs.

-new means we’re creating a new CSR,
-out defines the output file for the CSR,
-newkey rsa:2048 means create a new 2048 bit RSA key, -keyout defines the output file for the key, and
-sha256 means the CSR will request to be signed using the SHA-256 algorithm. SHA-256 is considered to be a secure hashing algorithm at the time I’m writing this article, and the same is true for 2048-bit RSA public/private keys.

We’ll be using a passphrase to secure the key (what we entered in response to “Enter PEM pass phrase:”); if you don’t want to secure the key with a passphrase, you can add the -nodes option to the end of the openssl req command, which tells it not to encrypt the private key.

Signing

Now the CSR is ready to be given to a commercial or internal CA for signing, and we would get back a valid certificate. For the remainder of this article, we will be assuming that we are working with a certificate in PEM format. For more on certificate format, see my article on how certificates work. Make sure to save the key created above, and be careful to keep it secure; the key is what the server will use to prove that it owns the certificate.

Adding the Certificate Chain

Appending a certificate’s chain to the certificate is not always necessary, but can make it easier for certain clients and servers to verify the validity of a certificate. If you got your certificate from a commercial CA, or an internal CA at a company, they probably make their certificate chain available somewhere. Combining the certificate and chain can be done with cat (which, oddly, is short for concatenate):

dogoncouch@localhost:~$ cat myserver.pem cert-chain.pem > myserver-with-chain.pem

If there are multiple CA certificates in the chain, you can append them in order of lowest (the CA certificate that signed your server’s certificate) to highest:

dogoncouch@localhost:~$ cat myserver.pem intermediate.pem root.pem > mycert-with-chain.pem

At this point, we can verify the contents of our certificate using another openssl subcommand: openssl x509, which deals with X.509 certificates. The -text option will output the certificate’s contents as text, and the -noout option means we don’t want to output the certificate in PEM format.

dogoncouch@localhost:~$ openssl x509 -text -noout -in myserver.pem 
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 10268757895948020715 (0x8e81f4e670782beb)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=New Jersey, L=Jersey City, O=dogoncouch.net, OU=NetLab, CN=myserver.dogoncouch.net
        Validity
            Not Before: Oct  8 19:03:52 2020 GMT
            Not After : Oct  8 19:03:52 2021 GMT
        Subject: C=US, ST=New Jersey, L=Jersey City, O=dogoncouch.net, OU=NetLab, CN=myserver.dogoncouch.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b8:ce:74:1d:52:3a:cf:74:65:64:e6:e2:11:2f:
                    88:c4:35:68:3f:1b:73:63:f4:7e:a5:14:eb:a8:0a:
                    57:9d:f5:bd:db:64:61:05:c8:16:e0:e1:0b:80:b6:
                    d2:dd:cb:77:3f:32:ad:a3:8e:e0:d3:a3:d3:30:5a:
                    d1:3e:1e:cb:fb:07:6e:bc:c9:ba:34:f2:98:98:ab:
                    94:0b:a6:38:4e:f9:3f:b7:ed:7f:4e:fa:5d:fe:c4:
                    8b:23:2f:93:f8:87:e5:e4:ee:fc:70:5d:94:76:b1:
                    df:2c:0d:72:ee:3a:33:75:1c:24:a4:74:cf:43:19:
                    b6:5d:12:55:3d:d2:1d:aa:f8:4a:2b:4d:f1:fd:fd:
                    81:78:45:bd:7d:a1:95:b2:4b:4c:5f:3c:69:e4:5b:
                    c1:b9:1c:d7:8d:ee:ca:d0:94:1d:81:f7:de:a4:e8:
                    f7:16:e4:6f:c0:5b:d9:ea:26:2d:43:9a:f7:fb:c7:
                    f3:42:02:b4:2b:db:84:8c:dd:79:9b:76:2e:52:38:
                    1b:8e:f2:7b:c7:02:56:91:f1:10:93:07:89:17:1f:
                    90:bf:11:8c:a4:dd:50:c5:16:81:5b:79:cf:c5:06:
                    5b:f5:e7:e9:4c:a7:79:12:ae:17:c0:12:b3:8f:bb:
                    f3:4f:7d:23:82:2a:8d:43:60:8d:66:05:2f:3e:64:
                    0a:d7
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         49:b4:d9:dc:a6:65:ba:2e:19:65:74:28:47:b2:e6:99:0c:45:
         f1:12:af:94:82:8d:2f:54:f3:b0:e8:e2:15:4b:70:90:13:8a:
         08:89:0d:22:48:96:73:3f:14:25:66:26:e0:ea:5d:ab:ee:2a:
         1b:86:dc:18:1d:30:1b:d0:5f:6f:c8:36:31:c8:16:cb:9e:fb:
         58:aa:b0:81:37:b8:69:20:53:2f:73:52:71:1a:17:0e:20:7e:
         07:06:c1:71:d8:d9:34:d9:a1:c2:d2:94:78:cb:69:23:1f:ac:
         c6:80:d8:14:d1:35:e6:f3:90:80:79:63:f6:c1:96:a6:ff:4f:
         f2:37:df:72:ad:5c:32:ab:4d:08:a4:d3:69:22:6a:74:d2:d1:
         3d:9f:e2:e9:d1:bd:a2:d4:1d:f0:4f:15:b8:fa:de:34:c9:9b:
         70:59:3f:09:98:92:af:6b:eb:aa:ba:d5:68:24:4c:17:46:ed:
         77:39:79:6a:2d:99:d7:09:30:b1:ba:4f:42:25:c8:6a:d6:eb:
         c0:5b:d7:57:b3:0f:06:6c:38:1b:ca:4a:7e:c4:61:72:2d:ef:
         5e:2d:d8:f7:c7:b1:4f:72:b3:30:6c:16:d1:a4:ef:33:84:e8:
         b5:62:ae:67:fc:ba:fc:e6:7e:2a:6b:ba:39:c7:8f:54:8d:72:
         01:91:14:22

Converting to PKCS#12 Format

In some cases, it’s useful to combine a certificate and key into a single file. This could be done to make certificate distribution easier, or to deal with a program that requires a single file certificate and key. A good format for doing this is PKCS#12. Creating a PKCS#12 file from a certificate and key is a simple process using openssl pkcs12 (another openssl subcommand):

dogoncouch@localhost:~$ openssl pkcs12 -export -in myserver-with-chain.pem -inkey myserver.key -name cert > myserver.p12
Enter pass phrase for myserver.key:
Enter Export Password:
Verifying - Enter Export Password:

The first passphrase we entered is the secret we used to protect the key at the beginning of this article, and the second (typed twice to verify) will be used to protect the PKCS#12 file. The PKCS#12 passphrase can be left blank if this certificate is going to be used by a server that doesn’t support PKCS#12 passphrases, but most server applications do, and will have an option to configure a passphrase in the same place that the certificate location is configured.

Self-Signed Certificate

Self-signed certificates are sometimes used in cases where it isn’t possible or practical to use a CA-signed certificate, such as within a development environment. A self-signed certificate and key can be created and signed with one openssl command. We’ll need the same identity information that we needed to create a CSR for a CA-signed certificate.

dogoncouch@localhost:~$ openssl req -x509 -out myserver.pem -newkey rsa:2048 -keyout myserver.key -sha256 -days 365
Generating a 2048 bit RSA private key
......+++
.........................+++
writing new private key to 'myserver.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:US
State or Province Name (full name) []:New Jersey
Locality Name (eg, city) []:Jersey City
Organization Name (eg, company) []:dogoncouch.net
Organizational Unit Name (eg, section) []:NetLab
Common Name (eg, fully qualified host name) []:myserver.dogoncouch.net 
Email Address []:

We’re still using the openssl req sub-command, but we’re using the -x509 option to create an X.509 certificate (as opposed to a request), and we’re also defining a valid lifetime for the certificate with -days 365.

Now that the self-signed certificate has been created, if we want to convert it into a PKCS#12 key store, we can use the same process described above for CA-signed certificates.

Conclusion

OpenSSL is a complicated suite of programs, but using openssl from the command line to perform basic functions with certificates, keys, and CSRs is a simple process. We looked at how to create a CSR for a CA-signed certificate, how to create a self-signed certificate, and how to add to a certificate by including its trust chain, or converting it to PKCS#12 format.

Leave a Reply

Your email address will not be published. Required fields are marked *