6

In Android N for SSL certificate i have to add this code-(according to given android developer link)

 <?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application> 

And a file network_security_config.xml in xml folder-

<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> </domain-config> 

This is working fine for one static domain but my problem is-The server domain will not same every-time in my application. Second problem is i am downloading SSL certificate from my server domain at run time so how can i update certificate file in raw folder every time because we know we can't write file in raw folder at run-time.

so for dynamic flow how can i connect to my server in Android N with different different certificates.

Edit1: If i am not using this config file code, my app communication stopped from server so i need to use this code anyway.

Edit2: This is my code in which i am connecting to my server and its giving me response 200 mean ok without changing code for android N (Old code).

 CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC"); InputStream caInput = new BufferedInputStream(new FileInputStream(certFile)); X509Certificate ca =(X509Certificate) cf.generateCertificate(caInput); String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); // Create a TrustManager that trusts the CAs in our KeyStore String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } }}; // Create an SSLContext that uses our TrustManager HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier()); SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, trustAllCerts, new java.security.SecureRandom()); // Tell the URLConnection to use a SocketFactory from our SSLContext url = new URL(wsdlUrl); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); urlConnection.setSSLSocketFactory(sslcontext.getSocketFactory()); urlConnection.setConnectTimeout(5000); urlConnection.connect(); if (urlConnection.getResponseCode() == 200) { //Successful response. result = true; } else { result = false; } 

but on 200 response i am calling my SOAP service method to that server, in this case i am getting exception

 com.neurospeech.wsclient.SoapFaultException: Server Error at com.neurospeech.wsclient.SoapWebService.postXML(SoapWebService.java:225) at com.neurospeech.wsclient.SoapWebService.getSoapResponse(SoapWebService.java:157) at com.vxlsoftware.fudmagent.serviceclasses.AndroidServiceAsync.access$1300(AndroidServiceAsync.java:6) at com.vxlsoftware.fudmagent.serviceclasses.AndroidServiceAsync$setAndroidClient HeartbitRequest.executeRequest(AndroidServiceAsync.java:367) at com.neurospeech.wsclient.ServiceRequest.run(ServiceRequest.java:20) at java.lang.Thread.run(Thread.java:761) 

Means my code of connnection url is working fine in Android N also but SOAP service giving me exception.

I think i didn't well defined my problem but please anyone who try please give me any clue.

6
  • The same way as on other Android versions. The new Android 7 network security configuration is not usable in your case. Commented Aug 31, 2016 at 11:47
  • @Robert - no i have to use it otherwise i am not able to communicate with my server.Actually i can't explain what actually i am doing but for your understanding i have to use this code of Android N other wise my app functioning will stop totally. Commented Aug 31, 2016 at 12:33
  • Did you find a solution to this problem? I am facing the same issue, and there doesn't seem to be any other way than going through a proxy that contains these keystores. Commented Oct 2, 2016 at 16:26
  • @IgorGanapolsky For android like i am calling service to test my connection in above code its working fine but if you are also using SOAP service then i don't have any solution right now. So if you are not using any soap service then you can use my above code to make a connection. Commented Oct 3, 2016 at 8:44
  • So your question is more about SOAP communication problem, rather than Android N network security. Is your SOAP code working on Marshmallow? Commented Oct 3, 2016 at 18:16

1 Answer 1

5

Network Security Config does not support dynamically defined trust anchors. Thus, you'll need to use the usual approach of creating a custom X509TrustManager which trusts the custom trust anchor(s), initializing an SSLContext from that, obtaining an SSLSocketFactory or SSLEngine from that, and passing that into your HTTPS stack. You'll have to be careful to trust such custom trust anchors only for connections to specific hosts. Otherwise, the entity which has the private key corresponding to the custom trust anchor can MiTM all network traffic from your app.

For an example, see https://developer.android.com/training/articles/security-ssl.html#UnknownCa. I suggest you modify the sample code to disable redirects on HttpsURLConnection.

Sign up to request clarification or add additional context in comments.

6 Comments

I would still need a keystore file for this to work. What if I'm connecting to many dynamic servers, and have no way of obtaining these keystore files?
You could add an X.509 certificate to the KeyStore on which the X509TrustManager you're using is based. You could also implement your own X509TrustManager which doesn't rely on a KeyStore.
Are you sure that would work on Android N? My tests confirm otherwise. Android N requires a physical keystore present on the device for self-signed certs!
I'm not sure what you mean by a "physical keystore present on the device". You can create an X509TrustManager from an in-memory KeyStore (e.g., developer.android.com/training/articles/…) or you can implement your own X509TrustManager that doesn't even use a KeyStore. You can then use the X509TrustManager to initialize an SSLContext which will then provide you with an SSLSocketFactory or SSLEngine.
Why not just add cipher suites that you need. Like: List<String> cipherSuitesToEnable = new ArrayList<>(); cipherSuitesToEnable.add("SSL_RSA_WITH_RC4_128_SHA"); cipherSuitesToEnable.add("SSL_RSA_WITH_3DES_EDE_CBC_SHA"); sslsock.setEnabledCipherSuites(cipherSuitesToEnable.toArray(new String[cipherSuitesToEnable.size()])); That should solve the problem with legacy Windows servers that demand different cipher suites as Android N.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.