We have mobile hybrid project running on MobileFirst 7.1.0.00.20170627-0807.
We have changed our Servers configuration to stop supporting TLS 1.0 and 1.1 and force it to use TLS 1.2 which broke our mobile app running on android devices 4.4.2 as it requires a native development to support it based on the references below:
ANDROID VERSIONS 4.4.2 AND EARLIER CANNOT CONNECT TO SERVER USING HTTPS IF ONLY TLS 1.2 IS ENABLED
We tried multiple solutions as referenced in the below blogs but with no luck:
Custom SSLSocketFactory Implementation to enable tls 1.1 and tls 1.2 for android 4.1 (16+)
How to enable TLS 1.2 support in an Android application
in my native code directory ca.company.project
I have added a Java file to support the custom SSLSocketFactory:
package ca.company.project;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
* @author fkrauthan
*/
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory internalSSLSocketFactory;
public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
internalSSLSocketFactory = context.getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return internalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return internalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if(socket != null && (socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"});
}
return socket;
}
}
And in my native code which is under the same directory MobileBanking.java I have added the below code for onCreate():
package ca.company.project;
import org.apache.cordova.CordovaActivity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.WindowManager.LayoutParams;
import android.content.pm.PackageManager;
import com.adobe.mobile.*;
import com.worklight.androidgap.api.WL;
import com.worklight.androidgap.api.WLInitWebFrameworkListener;
import com.worklight.androidgap.api.WLInitWebFrameworkResult;
import com.worklight.wlclient.api.WLClient;
import javax.net.ssl.SSLSocketFactory;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import android.os.*;
public class MobileBanking extends CordovaActivity implements WLInitWebFrameworkListener {
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
/*getWindow().setFlags(LayoutParams.FLAG_SECURE,
LayoutParams.FLAG_SECURE);*/
WL.createInstance(this);
try{
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
SSLSocketFactory noSSLv3Factory = null;
if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.KITKAT) {
noSSLv3Factory = new TLSSocketFactory();
} else {
noSSLv3Factory = sslContext.getSocketFactory();
}
HttpsURLConnection.setDefaultSSLSocketFactory(noSSLv3Factory);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
WL.getInstance().showSplashScreen(this);
WL.getInstance().initializeWebFramework(getApplicationContext(), this);
if(isTabletDevice(this)){
//Tablet
// System.out.println("isTablet oncreate");
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
} else {
//Phone
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
// Allow the SDK access to the application context
Config.setContext(this.getApplicationContext());
}
And it is not working, Any idea what I'm missing or what I need to change?