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
相关产品推荐
相关产品推荐

