Untrusted certificate using ksoap2-android

I am using ksoap2-android to call the wcf service over SSL. I can make it work without SSL, but now I want to make a call through SSL, but I ran into some problems.

I use HttpsTransportSE instead of HttpTransportSE, but I get the error: javax.net.ssl.SSLException: certificate without a trusted server

How can i fix this?

Can I add a server certificate in Keystore in Android to solve this problem?

private static final String SOAP_ACTION = "http://example.com/Service/GetInformation"; private static final String METHOD_NAME = "GetInformation"; private static final String NAMESPACE = "http://example.com"; private static final String URL = "dev.example.com/Service.svc"; public static Result GetInformation() { SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); PropertyInfo property = new PropertyInfo(); property.name = "request"; Request request = new Request("12", "13", "Ben"); userInformationProperty.setValue(request); userInformationProperty.setType(request.getClass()); request.addProperty(property); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(request); envelope.addMapping(NAMESPACE, "Request",new Request().getClass()); HttpsTransportSE transport = new HttpsTransportSE(URL, 443, "", 1000); //HttpTransportSE androidHttpTransport = new HttpTransportSE(URL); transport.debug = true; try { transport.call(SOAP_ACTION, envelope); return Result.FromSoapResponse((SoapObject)envelope.getResponse()); } catch (IOException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } return null; } 
+6
android soap ssl android-ksoap2
source share
4 answers

Well, there is an easier way to do this instead of changing the 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 executing any SSL connection / call on ksoap2. It will register a new default HostnameVerifier and TrustManager. ksoap2, when it makes its SSL connection, will use by default, and it works like a charm.

You can also make a few more efforts for this, make it much safer and install certificates in the local trusted application application, I think. I was on a secure network and not afraid of man-in-the-middle attacks, so I just made the first one.

I found it necessary to use KeepAliveHttpsTransportSE, like this new KeepAliveHttpsTransportSE(host, port, file, timeout); . Parameters fall into the URL object, for example, to access the Jira installation it is something like new KeepAliveHttpsTransportSE("host.whatever", 443, "/rpc/soap/jirasoapservice-v2", 1000) .

Sometimes it is convenient if you are new to the technology or web service that you want to use to play with it in the J2SE environment, and not in the emulator or even on the device, but in the j2SE / ME library ksoap2 (KeepAlive) No HttpsTransportSE ( I used ksoap2-j2se-full-2.1.2.jar). What you can do is get the sources for the three classes HttpsTransportSE, KeepAliveHttpsTransportSE and HttpsServiceConnectionSE from the Android android Android android android and put them in your J2SE project and use them. It worked for me, and it became a performance improvement to get the first steps with an unknown and rather complicated web service.

+4
source share

To complement Vedran's answer with some source code, sorry, I can not comment.

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

Your method call:

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

Notes:

  • Server is the URL of the server.
  • 443 is the default https port, you still need to specify the port, as the constructor expects it.
  • WS Operation Path URL
  • 1000 timeout

Which is built as: [Https: // server: 443 / URL]

+11
source share

KSOAP + WCF web service works for me 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 { } } 
+1
source share

Yes, maybe you can try this.

Https connection android

An error was found that was registered with Issue Tracker regarding this

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

0
source share

All Articles