Skip to main content

Tutorial: Create certificates using OpenSSL

TLS certificates are used to ensure the privacy and security of data in transit. TLS certificates can be created using the OpenSSL software and the TLS specification. For complete information on the TLS specification, see the IETF website.

Signed certificates are used in configuring the client-server secure connection. See Configure services for information on using TLS certificates to configure clients and servers.

Complete the procedures in this section to create a TLS certificate.

  1. Install OpenSSL version 3 or later.

  2. Open a command prompt.

  3. Create or navigate to a directory where you have write privileges — for example, C:\Certificates\.


    An equivalent location in Linux would be /home/user/Documents/Certificates/.

  4. Run hostname from the command prompt to get the name of the broker to use in the certificate creation.

    The hostname is returned.


    This hostname will be used as the common name in the certificate.  If the client is running on the same machine as the broker, localhost can be used as the hostname.

  5. Ping the returned hostname from the client machine to verify that you can communicate with it.

    > ping <hostname>

    The replies from the hostname are returned.

  1. Create a private certificate authority (CA) signing key named ca.key by running the following command from a command prompt:

    > openssl genrsa -aes256 -out ca.key 2048

    Alternatively, you can use the less secure -des3 instead of -aes256.

  2. Create a personal CA signing certificate named ca-cert-request.csr.


    If you set the OPENSSL_CONF environment variable, you can use the default settings for every prompt in this process (except the password) to unlock ca.key.

    1. Run the following command:

      > openssl req -new -key ca.key -out ca-cert-request.csr -sha256.

      The common name is intentionally not specified.

    2. Enter information as prompted.


      Do NOT use the arrow keys to fix mistakes. The arrow keys become part of the cryptogram.

    3. Alternatively, provide the "subject" values at the command line:

      > openssl req -new -key ca.key -out ca-cert-request.csr -sha256 -subj "/C=US/ST=Utah/L=Sandy/O=FairCom/OU=QA".

  3. Create a root certificate named ca-root-cert.crt for your personal CA.

    1. Use the key from Step 1 and the certificate from Step 2 .

    2. Run the following command:

      > openssl x509 -req -in ca-cert-request.csr -signkey ca.key -out ca-root-cert.crt -days 365 -sha256.

  4. Create a private key named server.key by running the following command:

    > openssl genrsa -out server.key 2048

  5. Create a certificate signing request named server-cert-request.csr to send to the personal CA for identity verification.

    1. Use the server.key from Step 4.

    2. Run the following command:

      > openssl req -new -key server.key -out server-cert-request.csr -sha256.

      You will be prompted for some settings values.

      • Common name is the hostname of the broker. An alternative to using the hostname of the broker is to use "localhost" for the common name.  However, this is less secure because the "localhost" can be used by nearly any machine.

      • The information you enter must NOT be an exact match to the information entered in Step 2, it must differ by at least one character in any field — for example, change FairCom to FairCom1.

        If the certificates appear identical, even though they were generated separately, the broker/client will not be able to distinguish between them, and you will experience difficult-to-diagnose errors. For more information, see Configure SSL/TLS support for Mosquitto.

      • If the common name is left blank in Step 2, and the common name is set to the hostname here, there should be no issues.

      Alternatively, run the following command with the "subject" values as a parameter:

      > openssl req -new -key server.key -out server-cert-request.csr -sha256 -subj "/C=US/ST=Utah/L=Sandy/O=FairCom1/OU=QA/CN=localhost".

  6. Create a new certificate named server.crt signed with your personal CA by running the following command:

    > openssl x509 -req -in server-cert-request.csr -CA ca-root-cert.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365.

  7. Verify the certificate is valid by running the following command:

    > openssl x509 -text -in server.crt -noout.

    The following results are displayed.

    Subject: O = FairCom, L = Sandy, ST = Utah, C = US, CN = localhost
    O is the organization
    L is the location (city)
    ST is the state
    C is the country
    CN is the common name (the hostname entered at the prompt)


Example 1. Invalid output from this verification

In this example, adam-dt-2019 was typed and then edited to localhost. The odd characters \1B[D and so forth, are the result of using the arrow keys to edit the string before hitting enter.

Subject: O = FairCom, L = Sandy, ST = Utah, C = US, CN = adam-dt-2019\1B[D\1B[D\1B[D\1B[D\1B[D\1B[D\1B[D\1B[Dh\1B[C\1B[D\1B[2~-lt-2021

Example 2. Paho Python error

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'localhost'. (_ssl.c:992)

Optionally, if you are creating more than one certificate, to save some time you can edit this sample for each certificate, rather than completing the steps in Create certificates using OpenSSL.

# OpenSSL configuration file.
# Establish a working directory.
dir                           = .

[ ca ]
default_ca                    = CA_default

[ CA_default ]
serial                        = $dir/serial
database                      = $dir/certindex.txt
new_certs_dir                 = $dir/certs
certificate                   = $dir/cacert.pem
private_key                   = $dir/private/ca.key
default_days                  = 365
default_md                    = sha256
preserve                      = no
email_in_dn                   = no
nameopt                       = default_ca
certopt                       = default_ca
policy                        = policy_match

[ policy_match ]
countryName                   = match
stateOrProvinceName           = match
organizationName              = match
organizationalUnitName        = optional
commonName                    = supplied
emailAddress                  = optional

[ req ]
default_bits                  = 2048         # Size of keys
default_keyfile               = key.pem      # name of generated keys
default_md                    = sha256       # message digest algorithm
string_mask                   = nombstr      # permitted characters
distinguished_name            = req_distinguished_name
req_extensions                = v3_req

[ req_distinguished_name ]
# Variable name               Prompt string
#-------------------------    ----------------------------------
0.organizationName            = Organization Name (company)
organizationalUnitName        = Organizational Unit Name (department, division)
emailAddress                  = Email Address
emailAddress_max              = 40
localityName                  = Locality Name (city, district)
stateOrProvinceName           = State or Province Name (full name)
countryName                   = Country Name (2 letter code)
countryName_min               = 2
countryName_max               = 2
commonName                    = Common Name (hostname, IP, or your name)
commonName_max                = 64

# Default values for the above, for consistency and less typing.
# Variable name               Value
#------------------------     ------------------------------
0.organizationName_default    = FairCom
localityName_default          = Sandy
stateOrProvinceName_default   = Utah
countryName_default           = US

[ v3_ca ]
basicConstraints              = CA:TRUE
subjectKeyIdentifier          = hash
authorityKeyIdentifier        = keyid:always,issuer:always

[ v3_req ]
basicConstraints              = CA:FALSE
subjectKeyIdentifier          = hash