Creating and Using Client Certificates with MQTT and Mosquitto

Another popular way of authenticating clients is via client certificates and can be use as in addition or as an alternative to using user name and password authentication.



In cryptography, a client certificate is a type of digital certificate that is used by client systems to make authenticated requests to a remote server.

Client certificates play a key role in many mutual authentication designs, providing strong assurances of a requester’s identity. –Wiki

A client certificate identifies the client just like the server certificate identifies the server.

Normally certificates are created and distributed to each client that connects to the server/broker that requires them.

However you can share a client certificate between clients.

As with username and password authentication the broker dictates whether or not a clients need to supply a certificate.

You can use certificates in combination with username and password authentication.

Mosquitto Broker Configuration

The main two settings are:

  • require_certificates – Main setting tells client it needs to supply a certificate when set to true. Default false
  • use_identity_as_username– – When set to true it tells mosquitto not to use the password file but to take the username from the certificate (common name given to certificate when you create it). Default false
  • crlfile – You can create a certificate revocation file that is used to revoke a client certificate

Creating Self SIgned Client Certificates

The client and server must use the same CA (certificate Authority)  for the client and server certificates.

You create the client certificates using the same process as you used for creating a server certificate.

  1. Create a client key  don’t password protect.
  2. Create a client certificate request using the key.
  3. Use the CA key to sign the client certificate request from step 2.

Preparation –

You need an existing CA certificate and private key which you get when you follow the steps for creating your own self signed server certificate.

You need to use the same CA for the client certificates as the server certificate, and the broker needs to use SSL.

This is because  client certificates require an encrypted connection.

If you don’t have a CA certificate then you need create one using the following:

First create a key for the CA

Command is:  openssl genrsa -des3 -out ca.key 2048

create-ca-key

Note: it is OK to create a password protected key for the CA.

Next:  Create a certificate for the CA using the CA key that we created in step 1

Command is:  openssl req -new -x509 -days 1826 -key ca.key -out ca.crt

create-ca-certificate

If you have followed the tutorial on creating server certificates then your folder should look like the one below:

ssl-directory

Step 1

The first step is to create a client private key.

The command is:

openssl genrsa -out client.key 2048

create-client key

Step 2

Next create a certificate request and use the client private key to sign it.

The command is:

openssl req -new -out client.csr -key client.key

You will be presented with a form that you need to complete.

The most important entry is the common name. This name can be used by the broker to indentify the client in place of a username.

client-certificate-request
Normally this certificate would be sent to a Certificate authority, but we are our own Certificate authority so we complete the request to create a client certificate

Step 3

Now we complete the request and create a client certificate. The command is:

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 360

create-client-certificate

This is now what our directory looks like

client-cetificates-final-folder

Using Client Certificates

To use client certificates the client requires three files:

  • ca.crt – The Certificate authority certificate
  • client.crt – The client certifcate file
  • client.key – The client private key

Publishing using Mosquitto_pub tool

The command is:

mosquitto_pub --cafile C:\ssl\ca.crt --cert C:\ssl\client.crt --key C:\ssl\client.key -d -h 192.168.1.157 -p 8883 -t test -m "hello there"

using-client-certificates.jpg

Note: You need to use the server name that is on the server certificate. If I use the IP address instead I get this error.

using-client-certificates-error

Publish Using Python

If you use Python you need to set the TLS settings  using:

client.tls_set('c:/ssl/ca.crt','c:/ssl/client.crt',\
'c:/ssl/client.key')

Publish Using Node-Red

On Node red you need to enable the SSL/TLS option in the broker settings.

tls-node-red

and then upload the client files as shown in the screen shot below:

client-certificates-node-red

Mosquitto Broker Connection

When the client connects to the broker and the use_identity_as_username is true then this is what you see:

mosquitto-broker-client-certs

Resources:

Example Mosquitto configuration file:

port 1883
log_type error
log_type notice
log_type information
log_type debug
#allow_anonymous false
#password_file /etc/mosquitto/pass.txt
#Extra Listeners
listener 8883
#ssl settings
cafile /home/steve/mos/certs/ca.crt
keyfile /home/steve/mos/certs/server.key
certfile /home/steve/mos/certs/server.crt
#client certifcate settings
require_certificate true
use_identity_as_username true

Terms Used

CA= Certificate Authority
Private Key = An encryption key that isn’t shared and needs to be stored securely
Public Key= An encryption key that is shared and doesn’t needs to be stored securely.
Certificate Request = An application for a certificate made to a certificate authority. Like a passport application

Shell Scripts

To save you typing I’ve created two Linux shell scripts that run the commands and create server and client certificates and keys as in this tutorial and the server certificate tutorial.

Related Tutorials

Please rate? And use Comments to let me know more
[Total: 2    Average: 5/5]

14 comments

  1. Hi Steve.
    First of all thank you for all of these information, but I want to know what is the purpose of these client step. What will happen if we use only ca.crt but not client.crt and client.key? Thank you in advance…

    1. Using the ca.crt only on the client is the way most clients will be configured. This mode is effectively the same mode as you use on a web browser when accessing a secure site.
      You only need client certificates if you want to use them to authenticate the client usually in place of a username/password authentication.
      DEoes that make sense?
      Rgds
      Steve

      1. Thank you for a quick response 🙂
        Now. I am trying to use client certificate but I am facing with the error:
        ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:661)
        when I try to connect. What can be the reason of this ? Btw
        my tls_set code is —-
        client.tls_set(‘/home/pi/Security/ca.crt’,’/home/pi/Security/client1.crt’,’/home/pi/Security/client1.key’)
        Is there any error here?
        Thx in advance again …

          1. My original conf file is like :
            port 1883
            listener 8883
            cafile /home/pi/Security/ca.crt
            keyfile /home/pi/Security/server.key
            certfile /home/pi/Security/server.crt

            I’m sorry for deleting by mistake.

          2. You also need these lines when using client certificates
            #client certifcate settings
            require_certificate true
            use_identity_as_username true
            rgds
            steve

        1. Hi Steve,
          Thanks for this awesome blog post!
          I am facing one challenge… I have a device certificate (device.pem) ,(devicekey.key) and secret key from the available device in cloud but I am confused which certificate do I need to use in tls_set().
          I have tried with eclipse paho tool and I have used cacerts (available in jre folder) with password “changeit” and devicekey.key as keystore and device secret as password.
          Please help and let me know if any other information is required.
          Thanks,
          Sunny

          1. Hi
            You need the Ca certificate the client certificate and the client key
            example

            client.tls_set(‘c:/ssl/ca.crt’,’c:/ssl/client.crt’,\
            ‘c:/ssl/client.key’)
            Rgds
            steve

          2. Hi Steve,
            Thanks for the help.
            I have provided all the certificates (ca.crt, client.crt, client.key) in tls_set but when I am trying to execute client.connect(broker,8883,timeout) I am getting [SSL:CERTIFICATE_VERIFY_FAILED] certificate verify failed : unable to get local issuer certificate (_ssl.c:1056)
            Trace back: selfobj.do_handshake()

            Please help !

            Thanks,
            Sunny

          3. This is usually caused by the common name on the server certificate being different to the name you use when you access the broker. If you use the insecure option in the client then it overrides the check and it should work. If it does then it is a clear sign that you have a name mismatch
            rgds
            steve

          4. Hi Steve,
            Thanks for the reply!
            Please help me in solving my confusion. What will be the use of the device certificate then if i will be using the certificated generated by me using openssl?
            I tried with the “MQTT.fx” and enabled “TLS/SSL” and “selected self sign certificates in keystore” option.
            my keystore file : cacerts -> got from jre folder where java is installed
            client keystore file : client.key
            client keystore is generated by “openssl pkcs12 -export -in certificate.pem -inkey certificate.pem -out client.ks”
            client keystore password : password from device certificate (generated automatically )
            client keypair password : same as client keystore password.

            so my confusion is what will be the values in tls_set parameter() ?

            Thanks for the help!

          5. Hi
            Client certificates are used instead of username/password authentication.
            Client certificates are considered more secure than username/password encryption but they are more difficult to set up and less well understood.
            However they need an encrypted connection to work and therefore the connection must use SSL.
            Does that make sense
            rgds
            steve

Leave a Reply

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