Not trusted certificate using ksoap2-android

前端 未结 4 1468
伪装坚强ぢ
伪装坚强ぢ 2020-12-06 02:57

I\'m using ksoap2-android to make a call to wcf service over SSL. I can get it to work without SSL, but now I want to make the call over SSL, but I\'ve run in to some proble

相关标签:
4条回答
  • 2020-12-06 03:47

    Well, there is an easier way to do this instead of modifying HttpsServiceConnectionSE. You can install a fake trust manager as described in http://groups.google.com/group/android-developers/browse_thread/thread/1ac2b851e07269ba/c7275f3b28ad8bbc?lnk=gst&q=certificate and then call allowAllSSL() before you do any SSL communication/call to ksoap2. It will register a new default HostnameVerifier and TrustManager. ksoap2, when doing its SSL communication, will use the default ones and it works like a charm.

    You can also put some more effort into this, make it (much) safer, and install certificates in an application local trust manager, I guess. I was in a safe network and not afraid of man-in-the-middle-attacks so I just did the first.

    I found it necessary to use KeepAliveHttpsTransportSE like this new KeepAliveHttpsTransportSE(host, port, file, timeout);. The parameters go into a URL object, so e.g. to access a Jira installation it's something like new KeepAliveHttpsTransportSE("host.whatever", 443, "/rpc/soap/jirasoapservice-v2", 1000).

    Sometimes its handy if you are new to the technology or the web service you like to use to play around with it in a J2SE environment instead of in the emulator or even on the device, but in the J2SE/ME ksoap2 library the (KeepAlive)HttpsTransportSE stuff is missing (I used ksoap2-j2se-full-2.1.2.jar). What you could do is to get the sources for the three classes HttpsTransportSE, KeepAliveHttpsTransportSE, and HttpsServiceConnectionSE from the Android spin-off ksoap2-android and put them into your J2SE project and use them. It worked for me and it became a productivity improvement to get the first steps right with an unknown and quite complex web service.

    0 讨论(0)
  • 2020-12-06 03:52

    Yes probably you can try this out

    Https Connection Android

    There has been a bug that has been filed on Issue Tracker regarding this

    http://code.google.com/p/android/issues/detail?id=2388

    0 讨论(0)
  • 2020-12-06 03:58

    Works for me KSOAP + Web service WCF with eclipse

    private static SoapObject getBody(final SoapSerializationEnvelope soapEnvelope) throws Exception {
            if (soapEnvelope.bodyIn == null) {
                throw new Exception("soapEnvelope.bodyIn=null");
            }
            else if (soapEnvelope.bodyIn.getClass() == SoapFault.class) {
                throw new ExceptionLogic((SoapFault) soapEnvelope.bodyIn));
            }
            else {
                return (SoapObject) soapEnvelope.bodyIn;
            }
    
        }
    
    private static SoapSerializationEnvelope sendRequete(final SoapObject soapReq, final String classMappingName,
                final Class<?> classMapping, final int timeOutSpecial) {
    
    
    
            final SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            soapEnvelope.implicitTypes = true;
            soapEnvelope.dotNet = true;
    
            if (classMappingName != null) {
                soapEnvelope.addMapping(NAMESPACE, classMappingName, classMapping);
            }
    
            soapEnvelope.setOutputSoapObject(soapReq);
    
            try {
    
                final HttpTransportSE httpTransport = new HttpTransportSE(Constante.urlWebService, timeOutSpecial);
                httpTransport.debug = BuildConfig.DEBUG;
    
                // Prod
                if (Constante.urlWebService.startsWith("https://")) {
                    final List<HeaderProperty> headerList = new ArrayList<HeaderProperty>();
                    headerList.add(new HeaderProperty("Authorization", "Basic "
                            + org.kobjects.base64.Base64.encode((Constante.CERTIFICAT_LOGIN + ":" + Constante.CERTIFICAT_MDP).getBytes())));
    
                    FakeX509TrustManager.allowAllSSL();
                    httpTransport.call(NAMESPACE + "/" + soapReq.getName(), soapEnvelope, headerList);
                }
                // Test
                else {
                    httpTransport.call(NAMESPACE + "/" + soapReq.getName(), soapEnvelope);
                }
    
                return soapEnvelope;
            }
            catch (final Exception e) {
                throw new Exception("Erreur : " + e.getMessage(), e);
            }
    
        }
    
    
    
        private static class FakeX509TrustManager implements X509TrustManager {
            private static TrustManager[] trustManagers;
            private final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};
    
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return _AcceptedIssuers;
            }
    
            public static void allowAllSSL() {
                HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    
                    @Override
                    public boolean verify(final String hostname, final 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 (final NoSuchAlgorithmException e) {
                    e.printStackTrace();
                }
                catch (final KeyManagementException e) {
                    e.printStackTrace();
                }
                HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
            }
    
            @Override
            public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException {
    
            }
    
            @Override
            public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
    
            }
        }
    
    0 讨论(0)
  • 2020-12-06 03:59

    To complement the answer of Vedran with some source code, sorry I can't comment.

    The trustManager:

    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 boolean isClientTrusted(X509Certificate[] chain) {
            return (true);
        }
    
        public boolean isServerTrusted(X509Certificate[] chain) {
            return (true);
        }
    
        public X509Certificate[] getAcceptedIssuers() {
            return (_AcceptedIssuers);
        }
    }
    
    public static void allowAllSSL() {
    
        javax.net.ssl.HttpsURLConnection
                .setDefaultHostnameVerifier(new HostnameVerifier() {
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
    
        javax.net.ssl.SSLContext context = null;
    
        if (trustManagers == null) {
            trustManagers = new javax.net.ssl.TrustManager[] { new _FakeX509TrustManager() };
        }
    
        try {
            context = javax.net.ssl.SSLContext.getInstance("TLS");
            context.init(null, trustManagers, new SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            Log.e("allowAllSSL", e.toString());
        } catch (KeyManagementException e) {
            Log.e("allowAllSSL", e.toString());
        }
        javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context
                .getSocketFactory());
    }
    

    The call at your method:

    allowAllSSL();
    HttpsTransportSE httpsTransport = new HttpsTransportSE(Server,443, URL, 1000);
    

    Notes:

    1. Server is the server url.
    2. 443 is the default https port, you still have to specify a port since the constructor expects one.
    3. URL the path to the WS operation
    4. 1000 es the timeout

    Which is constructed as: [https://Server:443/URL]

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