日本語

How to create a certificate with a private certificate authority

Overview

This page describes how to create a certificate required for SSL/TLS connection with a private certificate authority (CA).

The description will be made in the following order.

  1. Prerequisites
  2. Build a private certificate authority
  3. Create a server certificate
  4. Create a client certificate

Prerequisites

The following conditions are assumed for simplicity in this document.

The following values are used in the examples.

In practice, use appropriate values for your environment.

Build a private certificate authority

Here we show how to build a private certificate authority (CA) on Ubuntu 24.

The private certificate authority does not necessarily need to be built on the machine running the broker.

Install the openssl package.

Skip it if it is already installed.

$ sudo apt -y install openssl

Create a directory to store certificates and private keys.

$ sudo mkdir -p /etc/ssl/certs /etc/ssl/crl /etc/ssl/newcerts /etc/ssl/private

Edit the OpenSSL configuration file.

Edit the [ CA_default ] section of openssl.cnf as follows.

From the default openssl.cnf, just remove the comment symbol # before unique_subject and copy_extensions.

[ CA_default ]
dir             = /etc/ssl              # Where everything is kept
(omit)
unique_subject  = no                    # Set to 'no' to allow creation of
                                        # several ctificates with same subject.
(omit)
# Extension copying option: use with caution.
copy_extensions = copy

Create a file named index.txt to record the certificate signed by the private CA.

$ sudo touch /etc/ssl/index.txt

Create a CSR and private key for the CA certificate.

$ sudo openssl req -new -keyout /etc/ssl/private/cakey.pem \
       -out /etc/ssl/careq.pem -nodes \
       -subj /C=JP/ST=Example_State/O=Example_Organization/CN=private-ca

Create a self-signed CA certificate.

$ sudo openssl ca -batch -in /etc/ssl/careq.pem -selfsign -extensions v3_ca \
       -keyfile /etc/ssl/private/cakey.pem -days 3650 -create_serial \
       -out /etc/ssl/cacert.pem

Check the content of the created CA certificate.

$ openssl x509 -in /etc/ssl/cacert.pem -noout -text

The output should look like this:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ef:f1:65:60:87:be:24:2d
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Example_State, O=Example_Organization, CN=private-ca
        Validity
            Not Before: Feb 01 00:00:00 2020 GMT
            Not After : Jan 31 00:00:00 2023 GMT
        Subject: C=JP, ST=Default_Organization, O=Default_Organization, CN=private-ca
(omit)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                73:16:96:F1:00:79:31:FE:16:FD:73:C7:E7:C9:99:02:7D:0C:50:68
            X509v3 Authority Key Identifier:
                keyid:73:16:96:F1:00:79:31:FE:16:FD:73:C7:E7:C9:99:02:7D:0C:50:68

            X509v3 Basic Constraints:
                CA:TRUE
(omit)

Create a server certificate

Add the following lines to openssl.cnf to add the server’s hostname to the SAN (subjectAltName) of the certificate.

Change the hostname after DNS = according to your environment.

(omit)
[ req ]
(omit)
req_extensions = v3_req
(omit)
[ v3_req ]
subjectAltName = @alt_names
(omit)
[ alt_names ]
DNS = broker.example.org

Create a certificate signing request (CSR) and a private key for server certificate using the following command. Specify the output filename of the private key after -keyout, the output filename of the CSR after -out, and the subject of certificate after -subj.

$ sudo openssl req -new -keyout /etc/ssl/private/broker.key \
       -out /etc/ssl/broker.csr -nodes -subj /C=JP/CN=broker.example.org

Create a server certificate using the following command. Specify the private key filename after -keyfile, the CA certificate filename after -cert, the CSR filename after -in, and the output filename of the server certificate after -out.

$ sudo openssl ca -batch -keyfile /etc/ssl/private/cakey.pem \
      -cert /etc/ssl/cacert.pem -in /etc/ssl/broker.csr \
      -out /etc/ssl/certs/broker.crt -policy policy_anything

Check the content of the created server certificate.

$ openssl x509 -in /etc/ssl/certs/broker.crt -noout -text

The output should look like this:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ef:f1:65:60:87:be:24:2e
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Example_State, O=Example_Organization, CN=private-ca
        Validity
            Not Before: Feb 01 00:00:00 2020 GMT
            Not After : Jan 31 00:00:00 2023 GMT
        Subject: C=JP, CN=broker
(omit)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
(omit)
            X509v3 Subject Alternative Name:
                DNS:broker.example.org
(omit)

Create a client certificate

Create a certificate signing request (CSR) and a private key for client certificate using the following command. Specify the output filename of the private key after -keyout, the output filename of the CSR after -out, and the subject of certificate after -subj.

$ sudo openssl req -new -keyout /etc/ssl/private/client0.key \
       -out /etc/ssl/client0.csr -nodes -subj /C=JP/CN=client0

Create a client certificate using the following command. Specify the private key filename after -keyfile, the CA certificate filename after -cert, the CSR filename after -in, and the output filename of the client certificate after -out.

$ sudo openssl ca -batch -keyfile /etc/ssl/private/cakey.pem \
      -cert /etc/ssl/cacert.pem -in /etc/ssl/client0.csr \
      -out /etc/ssl/certs/client0.crt -policy policy_anything

Check the content of the created client certificate.

$ openssl x509 -in /etc/ssl/certs/client0.crt -noout -text

The output should look like this:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ef:f1:65:60:87:be:24:2f
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Example_State, O=Example_Organization, CN=private-ca
        Validity
            Not Before: Feb 01 00:00:00 2020 GMT
            Not After : Jan 31 00:00:00 2023 GMT
        Subject: C=JP, CN=client0
(omit)