HiveMQ Platform How-Tos
Configure server-side TLS with HiveMQ and Keytool (self-signed)
The next sections give you step-by-step instructions on how to configure server-side SSL/TLS with HiveMQ.
In this scenario, the client only validates the correct server certificate.
Generate a server-side certificate for HiveMQ
-
Execute the following command and enter all prompted information for the certificate:
keytool -genkey -keyalg RSA -alias hivemq -keystore hivemq.jks -storepass changeme -validity 360 -keysize 2048
We highly recommend that you update the changeme
default to a strong password.The first question asks about your first and last name. This is the common name of your certificate. Please enter the URL under which you will connect with your MQTT clients. For example, broker.yourdomain.com
(for production) orlocalhost
(for development). -
Select yes to confirm your entries.
-
Define a password for the newly generated key.
We highly recommend not to use the same password for the key and the key store. -
Place the
hivemq.jks
in the HiveMQ directory and add a TLS listener to theconfig.xml
file.<listeners> ... <tls-tcp-listener> <port>8883</port> <bind-address>0.0.0.0</bind-address> <tls> <keystore> <path>hivemq.jks</path> <password>your-keystore-password</password> <private-key-password>your-key-password</private-key-password> </keystore> <client-authentication-mode>NONE</client-authentication-mode> </tls> </tls-tcp-listener> ... </listeners>
The your-keystore-password
andyour-key-password
passwords depend on the passwords from the previous steps.
Generate a PEM client certificate (mosquitto_pub/_sub)
When you connect with mosquitto_pub/_sub command-line utilities, a PEM file of the certificate is required to allow the mosquitto clients to validate the self-signed certificate. You need to have access to the server key store generated in the above steps.
-
To export a PEM file from the server key store, enter:
keytool -exportcert -keystore hivemq.jks -alias hivemq -keypass your-key-password -storepass your-keystore-password -rfc -file hivemq-server-cert.pem
Be sure to replace your-keystore-password
andyour-key-password
in the command with your chosen passwords. -
To use the PEM with mosquitto_pub, enter:
mosquitto_pub -t "test/topic" -m "TLS works with client PEM" -p 8883 --cafile hivemq-server-cert.pem
Generate a client JKS trust store (Paho Java)
When you connect with a Java MQTT client, a JKS client key store is required to validate the self-signed certificate. You need to have access to the server key store generated in the above steps.
-
Export the server certificate from the server key store
keytool -export -keystore hivemq.jks -alias hivemq -storepass your-keystore-password -file hivemq-server.crt
Be sure to replace your-keystore-password
in the command with your chosen password. -
To generate a client trust store, enter:
keytool -import -file hivemq-server.crt -alias HiveMQ -keystore mqtt-client-trust-store.jks -storepass changeme
We highly recommend the use of a strong password instead of changeme
.-
Confirm the certificate with yes, before the trust store is successfully created.
-
-
Connect with Eclipse Paho
The following simple example only shows how to test if TLS is working.
For production usage, a more sophisticated implementation is necessary.Connect to HiveMQ with SSL using Eclipse Pahoprivate static Logger log = LoggerFactory.getLogger(PublisherSSL.class); public static void main(String... args) { try { String clientId = "sslTestClient"; MqttClient client = new MqttClient("ssl://localhost:8883", clientId, new MemoryPersistence()); MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); try { mqttConnectOptions.setSocketFactory(getTruststoreFactory()); } catch (Exception e) { log.error("Error while setting up TLS", e); } client.connect(mqttConnectOptions); client.publish("test/topic", "TLS works with client JKS!".getBytes(), 0, false); client.disconnect(); } catch (MqttException e) { log.error("MQTT Exception:",e); } } public static SocketFactory getTruststoreFactory() throws Exception { KeyStore trustStore = KeyStore.getInstance("JKS"); InputStream in = new FileInputStream("mqtt-client-trust-store.jks"); trustStore.load(in, "your-client-keystore-password".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore); SSLContext sslCtx = SSLContext.getInstance("TLSv1.2"); sslCtx.init(null, tmf.getTrustManagers(), null); return sslCtx.getSocketFactory(); }
Remember to replace the passwords in the snippet with your chosen passwords.
Configure TLS with HiveMQ and Portecle (self-signed)
-
Download and unzip the current version of Portecle.
-
To start Portecle, double-click the provided
portecle.jar
file or enterjava -jar portecle.jar
in the console:Portecle after start -
To create the server key store, select File → New Keystore from the menu and select JKS as key store type in the popup window:
Choose Java key store -
To create a new key pair, select Tools → Generate Key Pair and define the Key Algorithm and Key Size:
Common Key Algorithm and Size-
Enter the Signature Algorithm ( SHA512withRSA is recommended) and the Certificate Details:
Certificate Signature Algorithm and Details -
Choose a Key Pair Entry Alias:
An alias for the key pair -
Set a password for the Key Pair Entry:
A password to protect the private keySuccessful Generation of Key Pair -
To save the key store, define File → Save Keystore As…:
Save the key store
-
-
To export the certificate for the client, right-click the certificate key pair and select Export.
-
Select Head Certificate as Export Type and choose an export format ( PEM is recommended):
Export Details
-
-
Select Choose directory to save the certificate.
Export Successful -
Next, create the client key store
-
Select File → New Keystore from the menu and JKS as key store type.
-
Import the just saved certificate via Tools → Import Trusted Certificate.
-
Select the previous exported certificate:
Import server head certificate -
Confirm the message that the trust path could not be established.
This is because the certificate is self-signed and no certificate chain can verify it:Warning because of the self-signed certificate -
Confirm the showed certificate details:
Certificate Details -
To trust the certificate, click Yes.
Trust the created self-signed certificate for the server -
Enter an alias:
Alias for the server certificate in the client key storeSuccessful import of the server certificate in the client key store -
Save the key store as client.jks with File → Save Keystore As….
-
-
Place the server.jks in the HiveMQ directory and add a TLS listener to config.xml.
<listeners> ... <tls-tcp-listener> <port>8883</port> <bind-address>0.0.0.0</bind-address> <tls> <keystore> <path>server.jks</path> <password>your-keystore-password</password> <private-key-password>your-key-password</private-key-password> </keystore> <client-authentication-mode>NONE</client-authentication-mode> </tls> </tls-tcp-listener> ... </listeners>
-
Use
client.jks
to connect with a client.
Configure TLS with client certificates (self-signed) for HiveMQ using Keytool
Configure with PEM files (for mosquitto_pub/_sub and other clients)
-
Follow the procedures to Generate a server-side certificate for HiveMQ and Generate a PEM client certificate.
-
Make sure the server-side TLS works with mosquitto_pub/_sub and HiveMQ.
-
Generate client certificates.
This step needs to be done for each client that connects to HiveMQ. Also this is not the only way on how to create certificates. There are different options depending on your use case and capabilities. -
To generate a client certificate for PEM-based clients such as mosquitto_sub/_pub, execute the following command for each client:
openssl req -x509 -newkey rsa:2048 -keyout mqtt-client-key-2.pem -out mqtt-client-cert-2.pem -days 360
Enter all prompted information for the certificate.
You end up with two PEM files: mqtt-client-key-2.pem and mqtt-client-cert-2.pem.
-
-
Create a trust store for HiveMQ.
When the client connects with a certificate, HiveMQ needs a trust store in order to validate the self-signed certificates. You need to have access to all certificate PEM files generated in the previous step.
-
To export the client certificate from the PEM certification file, enter:
openssl x509 -outform der -in mqtt-client-cert-2.pem -out mqtt-client-cert-2.crt
-
To generate one common server trust store, execute the following command for each client certificate:
keytool -import -file mqtt-client-cert-2.crt -alias client2 -keystore hivemq-trust-store.jks -storepass changeme
We highly recommend the use of a strong password instead of changeme
.Confirm the certificate with yes, before the trust store is successfully created.
-
-
Change the
config.xml
in the HiveMQ home directory<listeners> ... <tls-tcp-listener> ... <tls> <keystore> ... </keystore> <client-authentication-mode>REQUIRED</client-authentication-mode> <truststore> <path>hivemq-trust-store.jks</path> <password>your-hivemq-trust-store-password</password> </truststore> </tls> </tls-tcp-listener> ... </listeners>
-
Connect with mosquitto_pub/_sub to HiveMQ
In the code example, we use the previously generated client trust store (hivemq-server-cert.pem) and the just generated PEM files to set up a full TLS client authentication to HiveMQ.
mosquitto_pub -t "test" -m "test" -p 8883 --cert mqtt-client-cert-2.pem --key mqtt-client-key-2.pem --cafile hivemq-server-cert.pem
-
Configure with Java Key stores (Eclipse Paho Java clients)
-
Follow the procedures to Generate a server-side certificate for HiveMQ and Generate a PEM client certificate.
-
Make sure the server-side TLS works with Eclipse Paho and HiveMQ.
-
To generate a client certificate for each Eclipse Paho Java client, execute the following command for each client and enter all prompted information for the certificate:
keytool -genkey -keyalg RSA -alias mqtt-paho-client-1 -keystore mqtt-paho-client-1.jks -storepass changeme -validity 360 -keysize 4096
We highly recommend the use of a strong password instead of changeme
.This step needs to be done for each client that connects to HiveMQ. Also, this is not the only way to create certificates. There are different options depending on your use case and capabilities. -
Generate one common server trust store for HiveMQ.
When the client connects with a certificate, HiveMQ needs a trust store to validate the self-signed certificates. You need to have access to all client key stores generated in the previous step.
-
To export the client certificate from each of the client key stores, enter:
keytool -export -keystore mqtt-paho-client-1.jks -alias mqtt-paho-client-1 -storepass your-client-keystore-password -file mqtt-paho-client-1.crt
Remember to replace your-client-keystore-password
in the command with your chosen key store password. -
To generate a server trust store, execute the following command for each client certificate:
keytool -import -file mqtt-paho-client-1.crt -alias client1 -keystore hivemq-trust-store.jks -storepass changeme
We highly recommend the use of a strong password instead of changeme
.-
Confirm the certificate with yes, before the trust store is successfully created.
-
-
Change the
config.xml
in the HiveMQ home directory:<listeners> ... <tls-tcp-listener> ... <tls> <keystore> ... </keystore> <client-authentication-mode>REQUIRED</client-authentication-mode> <truststore> <path>hivemq-trust-store.jks</path> <password>your-hivemq-trust-store-password</password> </truststore> </tls> </tls-tcp-listener> ... </listeners>
-
Connect with Paho
In the code example, we use the previously generated client trust store and the just generated client key store to set up a full TLS client authentication with Eclipse Paho for Java
This simple example only tests whether TLS is working. For production usage, a more sophisticated implementation is necessary. Connect to HiveMQ with SSL using Eclipse Pahoprivate static Logger log = LoggerFactory.getLogger(PublisherClientCertSSL.class); public static void main(String... args) { try { String clientId = "sslTestWithCert"; MqttClient client = new MqttClient("ssl://localhost:8883", clientId, new MemoryPersistence()); MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); try { mqttConnectOptions.setSocketFactory(getTruststoreFactory()); } catch (Exception e) { log.error("Error while setting up TLS", e); } client.connect(mqttConnectOptions); client.publish("test", "test".getBytes(), 1, true); client.disconnect(); } catch (MqttException e) { log.error("MQTT Exception:",e); } } public static SocketFactory getTruststoreFactory() throws Exception { //Create key store KeyStore keyStore = KeyStore.getInstance("JKS"); InputStream inKey = new FileInputStream("mqtt-paho-client-1.jks"); keyStore.load(inKey, "your-client-key-store-password".toCharArray()); KeyManagerFactory kmf = KeyManagerFactory .getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(keyStore,"your-client-key-password".toCharArray()); //Create trust store KeyStore trustStore = KeyStore.getInstance("JKS"); InputStream in = new FileInputStream("mqtt-client-trust-store.jks"); trustStore.load(in, "your-client-trust-store-password".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(trustStore); // Build SSL context SSLContext sslCtx = SSLContext.getInstance("TLSv1.2"); sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers() , null); return sslCtx.getSocketFactory(); }
Remember to replace the passwords in the snippet with your chosen passwords.
-