paho.mqtt.android
paho.mqtt.android copied to clipboard
android mqtt ssl connection not working in android 7
Please fill out the form below before submitting, thank you!
- [x] Bug exists Release Version 1.1.1 (Java Repository Master Branch)
- [ ] Bug exists in Snapshot Version 1.1.2-SNAPSHOT (Android Service Repository Master Branch)
- [ ] Bug is just in the Sample Application.
Android API Version Bug Seen on: 25
Android Version Bug Seen on: 7
Please also check that if you have found the bug in the Release version (1.1.1) that you check that it also exists in the Snapshot (1.1.2-SNAPSHOT) before raising a bug.
Description of Bug:
Mqtt SSL connection is not working in Android Nougat and this working well bellow android 7.
I am using following code to connect with mqtt:
final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(MainActivity.this, "ssl://" + pref.getMqttUrl(), clientId, persistence);
try {
String clientId = MqttClient.generateClientId();
MqttConnectOptions connectionOptions = new MqttConnectOptions();
connectionOptions.setCleanSession(true);
Log.e("Test", "ssl://" + pref.getMqttUrl());
try {
InputStream trustStoresIs = context.getResources().openRawResource(R.raw.ca_key);
String trustStoreType = KeyStore.getDefaultType();
KeyStore trustStore = KeyStore.getInstance(trustStoreType);
trustStore.load(trustStoresIs, context.getString(R.string.bks_password).toCharArray());
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(trustStore);
InputStream keyStoreStream = context.getResources().openRawResource(R.raw.user_cer_key);
KeyStore keyStore = null;
keyStore = KeyStore.getInstance("BKS");
keyStore.load(keyStoreStream, context.getString(R.string.bks_password).toCharArray());
KeyManagerFactory keyManagerFactory = null;
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, context.getString(R.string.bks_password).toCharArray());
SSLContext context = SSLContext.getInstance("SSL");
context.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) context.getSocketFactory();
connectionOptions.setSocketFactory(sslsocketfactory);
} catch (KeyManagementException | CertificateException | KeyStoreException | IOException | NoSuchAlgorithmException | UnrecoverableKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mqttAndroidClient.connect(connectionOptions, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.e("Mqtt","Connection Success!");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("Mqtt","Connection Failure!");
}
});
mqttAndroidClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
Log.e("Mqtt","Connection was lost!");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("mqtt Delivery Complete!");
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
Console Log output (if available):
Mqttjavax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
This sounds like the certificate is not in the trust store, this is something that you would need to manage yourself by adding the certificate to the trust store.
Did the issue resolve with the suggestion provided by @jpwsutton?
I found android mqtt ssl connection working well in android 7,but return SSLHandshakeException below android 7,even if I set the return value of verify from HostnameVerifier interface true.Do you know how to solve this problem?
@RamboWong2015 try this https://github.com/eurbon/Paho-MQTT-Android-TCP-TLS-WSS-Example
Hi How to get key file i.e. R.raw.ca_key and R.raw.user_cer_key?
I try this code but getting Hadshake issue, can you please share update code. @RamboWong2015 @sukhwinder-kaur , i was use @eurbon code but i have 3 certificate like "cert_ca.pem" ,"cert_cert", "cert_priv" how to use in your code. can yu provide demo code please?
Thanks is Advance.
I made it work.
You should combine the Certificate and the Private Key to form a BKS keystore (user_cer_key.bks)
This keystore corresponds to
InputStream keyStoreStream = getResources().openRawResource(R.raw.user_cer_key);
in the above code sample.
Below are commands of forming the BKS keystore:
-
First, combine the Certificate and the Private Key to form a pkcs12 keystore
openssl pkcs12 -export -inkey your_private_key.pem -in your_certificate.pem -out user_cer_key.p12
-
and then change the user_cer_key.p12 keystore to BKS keystore format :
keytool -importkeystore -srckeystore user_cer_key.p12 -srcstoretype pkcs12 -destkeystore user_cer_key.bks -deststoretype bks -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk15on-161.jar
The file bcprov-jdk15on-161.jar you can download from the Website of Bouncy Castle
ANDROID 7.1.2
Caused by: MqttException (0) - javax.net.ssl.SSLHandshakeException: Chain validation failed
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.lang.Thread.run(Thread.java:761)
Caused by: javax.net.ssl.SSLHandshakeException: Chain validation failed
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361)
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)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.security.cert.CertificateException: Chain validation failed
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:610)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:444)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:464)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:401)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:375)
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:304)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
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)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:156)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:301)
at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:606)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:444)
at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:464)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:401)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:375)
at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:304)
at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
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)
at java.lang.Thread.run(Thread.java:761)
how to solve it?