How to make MQTT connection work over SSL - Hill30/mqtt-client GitHub Wiki

The target use case to be covered consists of a central broker running ActiveMQ with MQTT Connector on one end (broker) and MQTT client, based on Eclipse PAHO client Java library on the other end (client). In order to make the broker and the client talk over SSL, both parties have to be supplied with necessary digital certificates.

The broker identity can be confirmed by the client by validating information sent by the broker using the public key of the broker certificate. If necessary the client identity can also be validated by running the same validation process in the opposite direction using client certificate. All this magic is implemented by the selected libraries - no additional coding required. Only the broker identity confirmation is required for our use case.

With these limitations in mind we only need one certificate. It should be installed in the broker's keystore, so that the private key in this certificate can be used during the SSL handshake. Also the public key of the certificate should be installed in the truststore on the client, so that the client will be able to play its part in the handshake.

Here is the steps to go through to make it happen:

1. Download KeyStore Explorer

KeyStore Explorer GUI (open source) tool can be downloaded here

Use KeyStore Explorer for actions with keystore, truststore and certificates.

2. Obtain a certificate

You can supply the client's truststore as a part of the consuming application, therefore it is O.K. to use a self signed certificate generated by a tool of your choice. The resulting .pfx file contains both private and public key.

But if you use certificate, generated by certification center, you don't have to distribute truststore with client. Client will trust broker because of certificates chain.

3. Configure the broker

3.1 create a backup copy of the default keystore - it is the broker.ks file in the ActiveMQ conf directory

3.2 the default broker.ks file contains an expired certificate MQTTBroker.ks - delete it.

3.3 Import into the existing broker.ks the PKF file with the certificate which includes both Private and Public keys.

3.4 Add SSL context to the ActiveMQ configuration read here for more details

   <sslContext>
     <sslContext keyStore="file:${activemq.base}/conf/broker.ks" keyStorePassword="password"/>
   </sslContext>

3.5. Change SSL configuration for MQTT connector:

         <transportConnector name="mqtt+nio+ssl" uri="mqtt+nio+ssl://0.0.0.0:8883?...

4. Configure client

4.1 For certificate from certification center

Sure that strings

  • SSLClientStore
  • SSLClientStorePswd

in file mqtt-client/mqttClient/src/main/res/values/strings.xml are empty

4.2 For self-signed certificate

4.2.1. Using KeyStore Explorer create BKS type store MQTTClient.bks Bouncy Castle

4.2.2. Extract public certificate from PKF in PEM format using either KeyStore Explorer or keytool command:

  keytool -export -alias client_cert -keystore broker.ks -file cert_for_client

4.2.3. Using KeyStore Explorer import new exported broker public certificate to MQTTClient.bks

4.2.4. Copy keytrust store to be used by client (MQTTClient.bks) into android application's assets folder

4.2.5. Update String resources

  • brokerURL - needs to be starting with ssl (e.g. ssl://10.0.1.144:1883)
  • SSLClientStore - name of the keytrust file to be used by client (MQTTClient.bks)
  • SSLClientStoragePswd - password for client truststore file

Additional resources:

For ActiveMQ

On Key and Trust stores

Detailed info on SSL Certs

For Debugging

  1. Turn on tracing
    <transportConnector ...  trace="true"...
  1. In Broker startup file (activemq.bat) add SSL debugging option:
    SET ACTIVEMQ_DEBUG_OPTS=-Djavax.net.debug=ssl
⚠️ **GitHub.com Fallback** ⚠️