KSOAP 2 Android with HTTPS

后端 未结 4 1325
离开以前
离开以前 2020-11-28 09:11

I am using KSOAP2 to manage SOAP in Android but it use https for the SOAP url and I am getting this error: javax.net.ssl.SSLException: Not trusted server certificate
A n

相关标签:
4条回答
  • 2020-11-28 09:22

    I find the answer by myself

    • on ServiceConnectionSE.java add this for accept untrusted certificate:

      private TrustManager[] trustAllCerts = new TrustManager[]{
          new X509TrustManager() {
              public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                  return null;
              }
              public void checkClientTrusted(
                  java.security.cert.X509Certificate[] certs, String authType) {
              }
              public void checkServerTrusted(
                  java.security.cert.X509Certificate[] certs, String authType) {
              }
          }
      };
      
    • then in the constructor add this to allow untrusted certificates and not verified hostnames:

          try {
             SSLContext sc = SSLContext.getInstance("TLS");
             sc.init(null, trustAllCerts, new java.security.SecureRandom());
             HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
          } catch (Exception e) {
             e.getMessage();
          }
          connection = (HttpsURLConnection) new URL(url).openConnection();
          ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier());
      
    0 讨论(0)
  • 2020-11-28 09:25

    I can't comment yet so i post my comments to rallat answer here. His solution works but it needs further explanations. To run ksoap2 with ssl:

    1. Put ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar in a project
    2. Download ksoap2 sources from https://github.com/mosabua/ksoap2-android/tree/ (ksoap2 repository)
    3. Copy HttpTransportSE.java, ServiceConnectionSE.java (I also needed to copy Transport.java, ServiceConnection.java and HeaderProperty.java). Delete imports from those files and make sure that they use your files (not imports from ksoap2.jar)
    4. Use rallat answer ( I copy-pasted it):

      • ServiceConnectionSE.java add this for accept untrusted certificate:

        private TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
                }
            }
        };
        
      • then use this constructors to allow untrusted certificates and not verified hostnames:

        public ServiceConnectionSE(String url) throws IOException {
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                e.getMessage();
            }
            connection = (HttpsURLConnection) new URL(url).openConnection();
            ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier());
        }    
        
      • Second contructor

        public ServiceConnectionSE(Proxy proxy, String url) throws IOException {
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
             } catch (Exception e) {
                e.getMessage();
             }
             connection = (HttpsURLConnection) new URL(url).openConnection();
            ((HttpsURLConnection) connection).setHostnameVerifier(new AllowAllHostnameVerifier());
        
            connection.setUseCaches(false);
            connection.setDoOutput(true);
            connection.setDoInput(true);
        }
        
    5. In your code just use:

      HttpTransportSE aht = new HttpTransportSE(URL);    
      aht.call(SOAP_ACTION, envelope);
      

    Other things as in tutorials

    0 讨论(0)
  • 2020-11-28 09:35

    Create a new class FakeX509TrustManager to handle the certificate problem,

        FakeX509TrustManager.allowAllSSL();
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    

    The new created class is as the following:

    public class FakeX509TrustManager implements X509TrustManager { 
    
        private static TrustManager[] trustManagers; 
        private static final X509Certificate[] _AcceptedIssuers = new 
    X509Certificate[] {}; 
    
        @Override 
        public void checkClientTrusted(X509Certificate[] chain, String 
    authType) throws CertificateException { 
        } 
    
        @Override 
        public void checkServerTrusted(X509Certificate[] chain, String 
    authType) throws CertificateException { 
        } 
    
        public boolean isClientTrusted(X509Certificate[] chain) { 
                return true; 
        } 
    
        public boolean isServerTrusted(X509Certificate[] chain) { 
                return true; 
        } 
    
        @Override 
        public X509Certificate[] getAcceptedIssuers() { 
                return _AcceptedIssuers; 
        } 
    
        public static void allowAllSSL() { 
                HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() 
    { 
                        @Override 
                        public boolean verify(String hostname, SSLSession session) { 
                                return true; 
                        } 
    
                }); 
    
                SSLContext context = null; 
                if (trustManagers == null) { 
                        trustManagers = new TrustManager[] { new FakeX509TrustManager() }; 
                } 
    
                try { 
                        context = SSLContext.getInstance("TLS"); 
                        context.init(null, trustManagers, new SecureRandom()); 
                } catch (NoSuchAlgorithmException e) { 
                        e.printStackTrace(); 
                } catch (KeyManagementException e) { 
                        e.printStackTrace(); 
                } 
    
           HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); 
        } 
    
    } 
    
    0 讨论(0)
  • 2020-11-28 09:40

    Checking again this problem, I've discovered a more clean solution for me. No KSOAP2 files modification needed.

    In your project, link the ksoap2-android-assembly-3.0.0-jar, with no modifications.

    Next, create a file named SSLConnection.java with this code:

    package com.example.mypackage;
    
    import android.util.Log;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    public class SSLConection {
    
        private static TrustManager[] trustManagers;
    
        public static class _FakeX509TrustManager implements javax.net.ssl.X509TrustManager {
            private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[]{};
    
            public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                    throws CertificateException {
            }
    
            public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                    throws CertificateException {
            }
    
            public X509Certificate[] getAcceptedIssuers() {
                return (_AcceptedIssuers);
            }
        }
    
        public static void allowAllSSL() {
    
            javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
    
            javax.net.ssl.SSLContext context;
    
            if (trustManagers == null) {
                trustManagers = new TrustManager[]{new _FakeX509TrustManager()};
            }
    
            try {
                context = javax.net.ssl.SSLContext.getInstance("TLS");
                context.init(null, trustManagers, new SecureRandom());
                javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
            } catch (NoSuchAlgorithmException e) {
                Log.e("allowAllSSL", e.toString());
            } catch (KeyManagementException e) {
                Log.e("allowAllSSL", e.toString());
            }
        }
    }
    

    And just call to SSLConection.allowAllSSL(); before calling a server method via KSOAP2. It's all, works for me. All SSL certificates are accepted and I can use KSOAP2 with https protocol.

    0 讨论(0)
提交回复
热议问题