在Android OS 4.4.2 / MobileFirst Hybrid应用程序上启用TLS 1.2

时间:2017-07-20 18:54:54

标签: java android ibm-mobilefirst

我们在MobileFirst 7.1.0.00.20170627-0807上运行移动混合项目。

我们已经更改了我们的服务器配置以停止支持TLS 1.0和1.1并强制它使用TLS 1.2,这破坏了我们在Android设备4.4.2上运行的移动应用程序,因为它需要本机开发来支持它基于以下参考:

ANDROID VERSIONS 4.4.2 AND EARLIER CANNOT CONNECT TO SERVER USING HTTPS IF ONLY TLS 1.2 IS ENABLED

我们尝试了以下博客中引用的多种解决方案,但没有运气:

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

在我的本机代码目录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; } } 中我添加了一个Java文件来支持自定义SSLSocketFactory:

 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());
        }

在我的本机代码中,在同一目录下MobileBanking.java我为onCreate()添加了以下代码:

$valueArray = array(
       array(
       ':name'=>name1 , 
       ':lastname'=>lastname1 
        ) , 
       array(
       ':name' => name2 ,
       ':lastname' => lastname2
       )
    )

它没有用,不知道我错过了什么或者我需要改变什么?

1 个答案:

答案 0 :(得分:0)

我无法立即对您提供的代码发表评论,但我知道这个解决方案对于面临同样问题的其他MFP用户有效:

1)转到此GitHub repo,并参加&#34; TlsSniSocketFactory.java&#34;,&#34; IgnoreSSLTrustManager.java&#34;和&#34; SelfSignedTrustManager.java&#中的课程34 ;.请记住,IBM不提供此开源代码,IBM也不提供任何支持。

2)在您的应用程序中包含这些类 - 更改程序包名称以与您的应用程序保持一致。

3)在扩展CordovaActivity的应用程序主要活动中包含此方法:

private void replaceSocketFactory(LayeredSocketFactory tlsSocketFactory) {
        HttpClientManager manager = HttpClientManager.getInstance();
        HttpClient client=  manager.getHttpClient();
        SchemeRegistry schemeRegistry =  client.getConnectionManager().getSchemeRegistry();  
        Scheme httpsScheme = schemeRegistry.getScheme("https");
        schemeRegistry.unregister("https");
        Scheme newScheme = new Scheme("https", tlsSocketFactory, httpsScheme.getDefaultPort());
        schemeRegistry.register(newScheme);
    }

4)在WL.createInstance(this)之后立即从Activity.onCreate()方法调用此方法;

@Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        WL.createInstance(this);
        replaceSocketFactory(new TlsSniSocketFactory());

        WL.getInstance().showSplashScreen(this);

        WL.getInstance().initializeWebFramework(getApplicationContext(), this);
    }

我不确定您为何会看到此问题,因为您使用的MFP 7.1的版本包含此问题的修复程序。您可能需要删除&#34; android&#34;如果您之前已从不包含此修复程序的iFix版本更新,则应用程序中的环境会再次添加回来。