You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android端Paho与HiveMQ连接Mosquitto Broker的SSL问题求助

Android设备通过SSL连接Mosquitto Broker的问题

Mosquitto Broker配置无误,嵌入式设备使用lwIP MQTT客户端可正常连接,但Android设备上连接时遇到以下问题:

Eclipse Paho客户端问题

虽能成功连接Broker,但因适配AndroidX平台出现如下错误:

com.example.pahoclient: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

由于源码难以修改,无法解决该问题,因此转而使用HiveMQ客户端。

HiveMQ客户端问题

HiveMQ客户端更适配当前平台,但出现SSL证书未知错误,Broker日志如下:

1676863126: New connection from 207.216.33.43:54922 on port 8883.
1676863126: OpenSSL Error[0]: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown
1676863126: Client <unknown> disconnected: Protocol error.

Mosquitto Broker配置

listener 8883
#listener 1883
cafile certs/ca.crt
certfile certs/server.crt
keyfile certs/server.key
protocol mqtt
tls_version tlsv1.2


require_certificate false
allow_anonymous false
password_file certs/password
max_keepalive 5000

Paho客户端代码

package com.example.pahoclient

//import info.mqtt.android.service.MqttAndroidClient;
import android.app.Notification
import android.content.Context
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.android.service.MqttService
import org.eclipse.paho.client.mqttv3.*
import java.security.KeyStore
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManagerFactory


class MQTTClient(context: Context,
                 serverURI: String = "ssl://example.com:8883",
                 clientID: String = "nonNull") {
    companion object {
        private const val TAG = "MQTTClient"
        private val certString: String = "-----BEGIN CERTIFICATE-----
" +
                ...
                "rtVtZNE+luuMaDyGQYkNt3d1S3TWFVgd
" +
                "-----END CERTIFICATE-----
"

        private fun createSSLSocketFactory(): SSLSocketFactory? {
            val cf = CertificateFactory.getInstance("X.509")
            val cert = cf.generateCertificate(certString.byteInputStream()) as X509Certificate

            val ks = KeyStore.getInstance(KeyStore.getDefaultType())
            ks.load(null, null)
            ks.setCertificateEntry("ca", cert)

            val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
            tmf.init(ks)

            val sslContext = SSLContext.getInstance("TLS")
            sslContext.init(null, tmf.trustManagers, null)
            return sslContext.socketFactory
        }
    }

    private var mqttClient = MqttAndroidClient(context, serverURI, clientID)

    fun connect(username:   String               = "...",
                password:   String               = "...",
                cbConnect:  IMqttActionListener  = defaultCbConnect,
                cbClient:   MqttCallback         = defaultCbClient

    ) {

        mqttClient.setCallback(cbClient)

        val options = MqttConnectOptions()
        options.userName = username
        options.password = password.toCharArray()
        options.isCleanSession = false
        options.socketFactory = createSSLSocketFactory()
        options.keepAliveInterval = 20


        try {
            mqttClient.connect(options, null, cbConnect)
        } catch (e: MqttException) {
            e.printStackTrace()
        }
    }
}

HiveMQ客户端代码

package com.example.pahoclient


import android.R.attr.password
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.hivemq.client.mqtt.MqttClient
import com.hivemq.client.mqtt.mqtt3.Mqtt3AsyncClient
import java.security.KeyStore
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import javax.net.ssl.KeyManagerFactory
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManagerFactory


private val certString: String = "-----BEGIN CERTIFICATE-----
"+
...
"-----END CERTIFICATE-----"

class MainActivity : AppCompatActivity() {

    private var client: Mqtt3AsyncClient? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

/**Call the socket factory**/

        //CA stuff
        val cf = CertificateFactory.getInstance("X.509")
        val cert = cf.generateCertificate(certString.byteInputStream()) as X509Certificate

        val ks = KeyStore.getInstance(KeyStore.getDefaultType())
        ks.load(null, null)
        ks.setCertificateEntry("ca", cert)

        val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
        tmf.init(ks)

        client = MqttClient.builder()
            .useMqttVersion3()
            .identifier("my-mqtt-client-id")
            .serverHost("******.com")
            .serverPort(8883)
            .sslConfig()
                .keyManagerFactory(null)
                .trustManagerFactory(tmf)
                 .applySslConfig()
            .buildAsync()

        client?.connectWith()
            ?.simpleAuth()
            ?.username("******")
            ?.password("*****".toByteArray())
            ?.applySimpleAuth()
            ?.send()
            ?.whenComplete { connAck, throwable ->
                if (throwable != null) {
                    // handle failure
                } else {
                    // setup subscribes or start publishing
                }
            }
    }

}

疑问与需求

同一CA证书在两个客户端表现不同,HiveMQ是否需要客户端证书?已尝试加载CA证书及客户端证书连接HiveMQ,仍未解决问题,寻求相关建议。


内容的提问来源于stack exchange,提问作者terminalObserver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:45:26