I answer this to give an idea of the scenario and solution according to the Android developers site for others. I solved this with a custom trust manager.
The problem was a server certificate that is missing an intermediate certification authority. However, when the first path of the certificate certificate was completed somehow, and the result was a successful verification of the certificate path.
There is a solution for the Android developer site for this. he suggests using a custom trust manager that trusts this server certificate or offers the server to include the intermediate CA in the server chain.
custom trust manager. source: https://developer.android.com/training/articles/security-ssl.html#UnknownCa
// Load CAs from an InputStream // (could be from a resource or ByteArrayInputStream or ...) CertificateFactory cf = CertificateFactory.getInstance("X.509"); // From https://www.washington.edu/itconnect/security/ca/load-der.crt InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt")); Certificate ca; try { ca = cf.generateCertificate(caInput); System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); } finally { caInput.close(); } // Create a KeyStore containing our trusted CAs 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); // Create an SSLContext that uses our TrustManager SSLContext context = SSLContext.getInstance("TLS"); context.init(null, tmf.getTrustManagers(), null); // Tell the okhttp to use a SocketFactory from our SSLContext OkHttpClient okHttpClient client = new OkHttpClient.Builder().sslSocketFactory(context.getSocketFactory()).build();
UPDATE: My problem was resolved after adding an intermediate certificate authority to the certificate chain on the server side. This is the best solution. Combining the certificate with the application requires updating the application after the certificate expires or any other problems associated with certificate management.
UPDATE: 09/03/2017 The easiest way to upload a certificate file I found is to use the original resource.
InputStream caInput = new BufferedInputStream(context .getResources().openRawResource(R.raw.certfilename));
where certfilename is the certificate file placed in the / raw resources folder. Also okhttp sslSocketFactory(SSLSocketFactory sslSocketFactory) deprecated, and the proposed approach in okhttp api doc can be used.
Also, when receiving a certificate from the server, it is better to use openssl.
openssl s_client -connect {server-address}:{port} -showcerts
Because I used to grab this from firefox and ran into a situation where it was modified by virus protection.
Ruwanka madhushan
source share