TLS1.3 hivemq broker

Hi,

How can we configure secure TLS 1.3 for hivemq broker ?

Thanks !

Hello Rahul,

You can achieve this by setting it in the <protocols> tag in your HiveMQ configuration:

<hivemq>

    <listeners>
        <tls-tcp-listener>
            <port>8883</port>
            <bind-address>0.0.0.0</bind-address>
            <tls>
                <keystore>
                    ...
                </keystore>
                <truststore>
                    ...
                </truststore>
                <protocols>
                    <protocol>TLSv1.3</protocol>
                </protocols>
            </tls>
        </tls-tcp-listener>
    </listeners>

</hivemq>

- Yannick

1 Like

Hi @YannickWeber ,

Thanks for your support !

Do we have any specific mqtt client for to test TLSv1.3 because I feel like mqttfx does not support TLSv1.3 ??

Thanks !

Hello Rahul,

Option 1

If you are familiar with java coding you can always use our MQTT Client.

Example:

import com.hivemq.client.mqtt.MqttClient;
import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient;
import org.jetbrains.annotations.NotNull;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.nio.file.Path;
import java.security.KeyStore;
import java.util.List;

import static com.hivemq.client.mqtt.MqttGlobalPublishFilter.ALL;
import static java.nio.charset.StandardCharsets.UTF_8;

public class TlsClientExample {

    public static void main(final String @NotNull [] args) throws Exception {

        final String host = "your-host";
        final String username = "your-username";
        final String password = "your-password";

        final Path keystorePath = Path.of("/path/to/keystore.jks");
        final String privateKeyPassword = "private-key-password";
        final String keystorePassword = "keystore-password";
        final Path trustStorePath = Path.of("/path/to/truststore.jks");
        final String trustStorePassword = "trust-store-password";

        //create an MQTT client
        final Mqtt5BlockingClient client = MqttClient.builder()
                .useMqttVersion5()
                .serverHost(host)
                .serverPort(8883)
                .sslConfig()
                    .hostnameVerifier((hostname, session) -> true)
                    .trustManagerFactory(buildTrustManagerFactoryFromJKS(trustStorePath, trustStorePassword))
                    .keyManagerFactory(buildKeyManagerFactoryFromJKS(keystorePath, keystorePassword, privateKeyPassword))
                    .protocols(List.of("TLSv1.3"))
                .applySslConfig()
                .buildBlocking();

        //connect to HiveMQ Cloud with TLS and username/pw
        client.connectWith()
                .simpleAuth()
                .username(username)
                .password(UTF_8.encode(password))
                .applySimpleAuth()
                .send();

        System.out.println("Connected successfully");

        //subscribe to the topic "my/test/topic"
        client.subscribeWith()
                .topicFilter("my/test/topic")
                .send();

        //set a callback that is called when a message is received (using the async API style)
        client.toAsync().publishes(ALL, publish -> {
            System.out.println("Received message: " + publish.getTopic() + " -> " + UTF_8.decode(publish.getPayload().get()));

            //disconnect the client after a message was received
            client.disconnect();
        });

        //publish a message to the topic "my/test/topic"
        client.publishWith()
                .topic("my/test/topic")
                .payload(UTF_8.encode("Hello"))
                .send();
    }

    public static @NotNull KeyManagerFactory buildKeyManagerFactoryFromJKS(
            final @NotNull Path keyStorePath,
            final @NotNull String jksPassword,
            final @NotNull String clientKeyPassword) throws Exception {

        final KeyManagerFactory keyManagerFactory =
                KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        final KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(new FileInputStream(keyStorePath.toFile()), jksPassword.toCharArray());
        keyManagerFactory.init(ks, clientKeyPassword.toCharArray());
        return keyManagerFactory;
    }

    public static @NotNull TrustManagerFactory buildTrustManagerFactoryFromJKS(
            final @NotNull Path truststorePath,
            final @NotNull String password) throws Exception {

        final char[] checkedPassword = password.toCharArray();
        final TrustManagerFactory trustManagerFactory =
                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        final KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(new FileInputStream(truststorePath.toFile()), checkedPassword);
        trustManagerFactory.init(ks);
        return trustManagerFactory;
    }
}

Option 2

Another option is to use our MQTT CLI:

mqtt pub -h localhost -p 8883 -i myClient --capath /path/to/ca.pem --tls-version TLSv1.3 --cert /path/to/cert.pem --key /path/to/key.pem

Option 3

A third option would be to try: CorreoMQTT. I am not quite sure if it supports TLSv1.3 but it is based on the hivemq-mqtt-client so there would be a chance.

- Yannick

2 Likes

Hi @YannickWeber ,

Thanks for your support !

Iā€™m able to connect the broker now with TLSv1.3 there is some additional JRE version which support the tls1.3.

This code will really help me to understand better.

Thanks