B4J Question MQTT SSL handshake error

hookshy

Well-Known Member
Licensed User
Longtime User
I am using for my project :
local broker : JMQTTBROKER2
b4a client : jMQTT



I have generated a root.jks keystore and the server starts over SSL using this code:
B4X:
    Dim path As String
    path = File.ReadString(File.DirApp,"path.txt")
    Log(path)
  
'ssl only
    broker.Initialize("", 0) 'set the non-SSL port to 0
    broker.SetUserAndPassword("xxx", "1234") '(optional) set the username and password
    Dim jo As JavaObject = broker
    Dim config As JavaObject = jo.GetFieldJO("config")
    config.RunMethod("setProperty", Array("ssl_port", "8883"))
    config.RunMethod("setProperty", Array("key_manager_password", "xxx"))
    config.RunMethod("setProperty", Array("key_store_password", "xxx"))
    config.RunMethod("setProperty", Array("jks_path", path)) 'path to keystore file
  
    broker.DebugLog = True
    broker.Start

I have configured the client to trust all certificates as described by Errel
B4X:
Sub Process_Globals
   
    Private mqtt As MqttClient
    Private mytopic As String
    Private serializator As B4XSerializator
    Type CircleData (x As Double, y As Double, clr As Int)
    'Private serverURI As String = "tcp://10.0.2.2:51044" 'emulator
    Private serverURI As String = "ssl://192.168.0.14:8883"
    Dim timer1 As Timer
   
End Sub

Sub Globals
    Private Canvas1 As Canvas
    Private lblStatus As Label
    Private Button2 As Button
    Private Button1 As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        timer1.Initialize("timer1",1000)
           
        mqtt.Initialize("mqtt", serverURI, Rnd(0, 999999999) & DateTime.Now)
    
'second option     
    Dim mo As MqttConnectOptions
   mo.Initialize("xxx", "1234")
   Dim jo As JavaObject = mo
   jo.RunMethod("setSocketFactory", Array(CreateTrustAllSSLSocketFactory))
    mqtt.Connect2(mo) 
          
    timer1.Enabled=True
    Activity.LoadLayout("1")
    Canvas1.Initialize(Activity)
End Sub

Sub CreateTrustAllSSLSocketFactory As Object
  
    Dim tm As CustomTrustManager
    tm.InitializeAcceptAll
    Dim SSLContext As JavaObject
    SSLContext = SSLContext.InitializeStatic("javax.net.ssl.SSLContext").RunMethod("getInstance", Array("TLS"))
    SSLContext.RunMethod("init", Array(Null, tm, Null))
    Dim Factory As JavaObject = SSLContext.RunMethod("getSocketFactory", Null)
    Return Factory
End Sub




Q: If you tell client to trust all certificat means that the client does not care if the broker is trusted ?
If the broker generates a certificat for the client , how does the client use this certificat in my case a pem certificat ?


I have this error on the broker please advise:

B4X:
Waiting for debugger to connect...
Program started.
G:\Public\Gabi2020\basic4java\MQTT\BROKER_UI\MQTT_BROKER\Objects\root.jks
Configuring message interceptors...
Initializing broker interceptor. InterceptorIds=[]
Using default SSL context creator
Invoking constructor with io.moquette.broker.config.IConfig argument. ClassName=anywheresoftware.b4j.objects.MqttBroker$B4XAuthenticator, interfaceName=io.moquette.broker.security.IAuthenticator
Authorizator policy io.moquette.broker.security.PermitAllAuthorizatorPolicy instance will be used
Initializing CTrie
Initializing subscriptions store...
Netty is using NIO
Server bound to host=0.0.0.0, port=0, protocol=TCP MQTT
Property websocket_port has been setted to disabled. Websocket MQTT will be disabled
Checking SSL configuration properties...
Initializing SSL context. KeystorePath = G:\Public\Gabi2020\basic4java\MQTT\BROKER_UI\MQTT_BROKER\Objects\root.jks.
Loading keystore. KeystorePath = G:\Public\Gabi2020\basic4java\MQTT\BROKER_UI\MQTT_BROKER\Objects\root.jks.
No keystore has been found in the bundled resources. Scanning filesystem...
Loading external keystore. Url = G:\Public\Gabi2020\basic4java\MQTT\BROKER_UI\MQTT_BROKER\Objects\root.jks.
Initializing key manager...
Initializing SSL context...
The SSL context has been initialized successfully.
Server bound to host=0.0.0.0, port=8883, protocol=SSL MQTT
Property secure_websocket_port has been set to disabled. Secure websocket MQTT will be disabled
Moquette integration has been started successfully in 1984 ms
Unexpected exception while processing MQTT message. Closing Netty channel. CId=null
io.netty.handler.codec.DecoderException: javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.moquette.broker.metrics.BytesMetricsHandler.channelRead(BytesMetricsHandler.java:51)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1414)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:945)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:146)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:545)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
    at java.base/sun.security.ssl.ServerHello$T12ServerHelloProducer.chooseCipherSuite(ServerHello.java:461)
    at java.base/sun.security.ssl.ServerHello$T12ServerHelloProducer.produce(ServerHello.java:294)
    at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
    at java.base/sun.security.ssl.ClientHello$T12ClientHelloConsumer.consume(ClientHello.java:1101)
    at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:851)
    at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:810)
    at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1065)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1052)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:999)
    at io.netty.handler.ssl.SslHandler.runDelegatedTasks(SslHandler.java:1417)
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1325)
    at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1159)
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1203)
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
    ... 28 more
 
Last edited:

hookshy

Well-Known Member
Licensed User
Longtime User
I finaly found the problem with SSL handshake

B4X:
    Dim jo As JavaObject = broker
    Dim config As JavaObject = jo.GetFieldJO("config")
    config.RunMethod("setProperty", Array("ssl_provider", "JDK"))
    config.RunMethod("setProperty", Array("ssl_port", "8883"))
    config.RunMethod("setProperty", Array("key_manager_password", "xxxx"))
    config.RunMethod("setProperty", Array("key_store_password", "xxxx"))
    config.RunMethod("setProperty", Array("jks_path", path)) 'path to keystore file
    config.RunMethod("setProperty", Array("key_store_type", "jks"))
    config.RunMethod("setProperty", Array("host", "192.168.0.14"))


When you generate jks and export the certificate you must provide algoritm explicity for both operations
here is the code used to generate keys with keytool from java 11 sdk
B4X:
generate pem
keytool -genkeypair -keystore root.jks -alias root -keyalg RSA -ext bc:c
keytool -keystore root.jks -alias root -exportcert -keyalg RSA -rfc > root.pem

keystore password must math with the one that created the keystore with keytool
 
Upvote 0
Top