paho.mqtt.java icon indicating copy to clipboard operation
paho.mqtt.java copied to clipboard

SSLHandshakeException: No subjectAltNames on the certificate match

Open kavidriod opened this issue 6 years ago • 10 comments

Hi,

Please suggest.

I have Upgraded from version 1.2.0 to 1.2.1 ,When i try to connect i'm getting this issue

MqttException (0) - javax.net.ssl.SSLHandshakeException: No subjectAltNames on the certificate match

Below is a log from mosquitto

sslv3 alert certificate unknown

kavidriod avatar Jul 30 '19 09:07 kavidriod

Does the hostname that you connect with, appear in the Subject Alternative Name (SAN) section of the MQTT broker's TLS certificate? If you connect with the broker's IP address, then this IP address would also have to be a Subject Alternative Name.

sp193 avatar Aug 09 '19 17:08 sp193

@kavidriod Did you manage to fix this? I am using this with Android and I noticed that this happens only with certain kinds of devices

Fidenz-Lasithh avatar Nov 22 '19 05:11 Fidenz-Lasithh

Having the same issue with Miui 11 Android 9. I'm using a self signed ca cert.

1.2.0 works, 1.2.1 and 1.2.2 throws "javax.net.ssl.SSLHandshakeException: No subjectAltNames on the certificate match".

enesaltinkaya avatar Jan 03 '20 05:01 enesaltinkaya

Hi,

Please suggest.

I have Upgraded from version 1.2.0 to 1.2.1 ,When i try to connect i'm getting this issue

MqttException (0) - javax.net.ssl.SSLHandshakeException: No subjectAltNames on the certificate match

Below is a log from mosquitto

sslv3 alert certificate unknown

Have you found a solution? I also encountered the same problem

entrehuihui avatar Sep 11 '20 08:09 entrehuihui

Though it's not a good practice, but if you trust your broker and don't want to verify it's identity, you can build a fake trust manager as below which verifies nothing (no ca certificate usage at client side) and client gets connected to broker without any exception. ` private fun fakeSocketFactory() : SocketFactory { val trustManager = object: X509TrustManager { override fun checkClientTrusted(chain: Array<out java.security.cert.X509Certificate>?, authType: String?) {} override fun checkServerTrusted(chain: Array<out java.security.cert.X509Certificate>?, authType: String?) {} override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> = arrayOf() } val sslContext = SSLContext.getInstance("SSL") sslContext.init(null, arrayOf(trustManager), SecureRandom()) return sslContext.socketFactory }

private fun connect(){ ... val options = MqttConnectOptions() options.socketFactory = fakeSocketFactory() client.connect(options,null,object:IMqttActionListener{ ... }) ... } `

It's similar to chrome's warning "Your connection is not private. " and our action "Proceed to (unsafe)", though communication remains encrypted.

Manishoaham avatar Sep 11 '20 18:09 Manishoaham

I have resolved the said

"MqttException (0) - javax.net.ssl.SSLHandshakeException: No subjectAltNames on the certificate match"

error by adding one (can add multiple) alternative subject name in the server certificate (having CN=example.com) as below:

Subject Alternative Name: DNS: example.com

I used KeyExplorer on windows for generating my server certificate. You can follow this link for adding alternative subject names (follow the only part for adding it).

Manishoaham avatar Sep 13 '20 07:09 Manishoaham

This also applies to IP addresses. If you connect by IP address and it is not in the certificate's Subject Alternative Name (SAN) list, this error will occur.

sp193 avatar Sep 16 '20 15:09 sp193

Check this method. It worked for me.

HttpsURLConnection.setDefaultSSLSocketFactory(yourSslSocketFactoryObject) mqttConnectOptions2.socketFactory =yourSslSocketFactoryObject val allHostsValid: HostnameVerifier = HostnameVerifier { hostname, session -> true }

            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid)

VinayakMoger avatar Jan 28 '21 05:01 VinayakMoger

Yes, but please understand the security implications, if you work around this feature. It's meant to ensure that you are connecting to the right server, by checking that the server's certificate contains the hostname that is used for the connection.

sp193 avatar Jan 30 '21 07:01 sp193

Adding my two cents on this topic.

When connecting a MQTT client on Android with the Paho Java library to the mosquitto test broket, it appears that :

  • when enabling the hostNameVerification (default option) via isHttpsHostnameVerificationEnabled = true, the connection fails with the error No subjectAltNames on the certificate match
  • When setting isHttpsHostnameVerificationEnabled to False and implementing a SSLHostnameVerifier (hostname, sslSession) -> hostname.equals(sslSession.peerHost) the connection and the verification succeed. By manually inspecting the certificates returned by the server, they indeed seem to contain a SAN with the proper value (test.mosquitto.org).

From the documentation, it seems that the SSLHostnameVerifier is used after the TLS handshake, so maybe the isHttpsHostnameVerificationEnabled fails during the Handshake. Does anyone know the difference between the isHttpsHostnameVerificationEnabledfield and the SSLHostnameVerifier members in the MqttConnectOptions structure? The discussion leading to the add of the SSLHostNameVerifier does not seem to mention isHttpsHostnameVerificationEnabled member in his rationale, so I believe I miss something.

I understand the difference betweeen certificate chain validation and hostname verification, and in my use case certificate chain validation may be sufficient in terms of security, but I would like to understand why I need to disable the hostname verification to make it work.

Thanks for your help

lsouchet avatar Feb 07 '23 10:02 lsouchet