MQTT SSL connection failed for java client

612 views
Skip to first unread message

Nuwan Sameera

unread,
Oct 28, 2021, 5:42:43 AM10/28/21
to MQTT
Hi, 

I have rabbit mq server with mqtt enabled. It is ssl enabled and I have client certificate and key. It successfully connected from MQTTBox and python paho mqtt client. But java paho mqtt client given following error.

xception in thread "main" MqttException (0) - javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:738)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: unknown_ca
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:313)
at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:186)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1144)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1055)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:395)
at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:159)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:724)
... 1 more

maven dependency details

<!-- mqtt client-->
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.5</version>
</dependency>

<!-- ssl support -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>


Following is the java code I try to use

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;

import java.io.*;
import java.security.cert.*;
import javax.net.ssl.*;

public class ScioMQTTClient {

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

MqttClient mqttClient = new MqttClient("ssl://server:8883",
"clientId1", new MemoryPersistence());

MqttConnectOptions options = new MqttConnectOptions();
options.setUserName("user");
options.setPassword("password".toCharArray());

SSLSocketFactory socketFactory = getSocketFactory("ca_certificate.pem", "client_certificate.pem",
"client_key.pem", "");
options.setSocketFactory(socketFactory);

mqttClient.connect(options);

System.out.println("Connected");

}

static SSLSocketFactory getSocketFactory(final String caCrtFile, final String crtFile, final String keyFile, final String password) throws Exception {
Security.addProvider(new BouncyCastleProvider());

// load CA certificate
PEMReader reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(caCrtFile)))));
X509Certificate caCert = (X509Certificate) reader.readObject();
reader.close();

// load client certificate
reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(crtFile)))));
X509Certificate cert = (X509Certificate) reader.readObject();
reader.close();

// load client private key
reader = new PEMReader(
new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFile)))),
new PasswordFinder() {
public char[] getPassword() {
return password.toCharArray();
}
}
);
KeyPair key = (KeyPair) reader.readObject();
reader.close();

// CA certificate is used to authenticate server
KeyStore caKs = KeyStore.getInstance("JKS");
caKs.load(null, null);
caKs.setCertificateEntry("ca-certificate", caCert);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(caKs);

// client key and certificates are sent to server so it can authenticate us
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, null);
ks.setCertificateEntry("certificate", cert);
ks.setKeyEntry("private-key", key.getPrivate(), password.toCharArray(), new java.security.cert.Certificate[]{cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
kmf.init(ks, password.toCharArray());

// finally, create SSL socket factory
SSLContext context = SSLContext.getInstance("TLSv1.2");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return context.getSocketFactory();

}

}


What is the reason for this.

Following is the python code I use. It is working properly.

import paho.mqtt.client as mqtt

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))

client.subscribe("$SYS/#")

def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))

client = mqtt.Client()
client.username_pw_set("user", password="password")
client.on_connect = on_connect
client.on_message = on_message

client.tls_set(ca_certs="ca_certificate.pem", certfile="client_certificate.pem", keyfile="client_key.pem")

client.connect("server", 8883, 60)

client.loop_forever()

Domenico Briganti

unread,
Oct 28, 2021, 6:05:44 AM10/28/21
to MQTT
Are you using the same client certificate? The error Received fatal alert: unknown_ca means that the server does not know the autority that signed the client certificate.

Regards,
Domenico

Nuwan Sameera

unread,
Oct 28, 2021, 8:16:41 AM10/28/21
to MQTT
Yes both certificates sign in same CA. Problem is python client and MQTT box connected successfully.
Reply all
Reply to author
Forward
0 new messages