Heuristic Services     About     Archive     Feed


Using a directly-trusted server certificate

Moquette is a broker that supports SSL. In the Moquette documentation, it mentions you can generate a keypair as a Java keystore:

~$ keytool -keystore serverkeystore.pkcs12 -alias testserver -genkey -keyalg RSA

Make sure that the path to the keystore is the filesystem path, not the file:/// URL.

final String keystorePath = Objects.requireNonNull(Broker.class.getResource("serverkeystore.pkcs12")).getPath();
properties.put(SSL_PORT_PROPERTY_NAME, "8883");
properties.put(JKS_PATH_PROPERTY_NAME, keystorePath);
properties.put(KEY_STORE_PASSWORD_PROPERTY_NAME, "password");
properties.put(KEY_MANAGER_PASSWORD_PROPERTY_NAME, "password");

If you use a client such as the hivemq-mqtt-client, then you will find that it fails, as it fails to validate the Subject Alternative Name (SAN).

Exception in thread "main" com.hivemq.client.mqtt.exceptions.ConnectionFailedException: javax.net.ssl.SSLHandshakeException: No subject alternative names present

A certificate can be generated using a SAN, in this case for localhost:

keytool -keystore serverkeystore.pkcs12 -alias testserver -genkey -keyalg RSA -dname "CN=" -ext "SAN=IP:"

You can list the certificate in the keystore with:

keytool -list -keystore serverkeystore.pkcs12

We’ll need to add this certificate to the client’s (in this case HiveMQTT) trust store, so export the certificate using:

keytool -export -alias testserver -keystore serverkeystore.pkcs12 -file testserver.crt

You can inspect the certificate by using openssql and specifying it needs to read the DER binary format:

openssl x509 -inform der -in testserver.crt -text

Continue to follow the Moquette documentation to create a keystore that trusts this certificate for the client:

keytool -keystore clientkeystore.pkcs12 -genkey -keyalg RSA
keytool -keystore clientkeystore.pkcs12 -import -alias testserver -file testserver.crt -trustcacerts

Configure the HiveMQTT client to use this directly trusted certificate and subscribe to a test message:

public static void main(String[] args) throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, URISyntaxException, InterruptedException {
    final Mqtt3BlockingClient client = com.hivemq.client.mqtt.MqttClient.builder()

            .callback(e -> System.out.printf("%s %s", e.getTopic(), new String(e.getPayloadAsBytes())))

            .payload("Test message".getBytes(StandardCharsets.UTF_8))

private static TrustManagerFactory getTrustManagerFactory() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, URISyntaxException {
    final KeyStore keystore = KeyStore.getInstance("pkcs12");
    final InputStream in = new FileInputStream(Objects.requireNonNull(Client.class.getResource("clientkeystore.pkcs12")).getFile());
    keystore.load(in, "password".toCharArray());

    final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

    return trustManagerFactory;