The Problem
You are developing an application with its own backend server and you want to create a secure SSL connection from your Android app with a self signed certificate
You are
Solution
First we are going to add the certificate CA to the "res\raw" folder in this case the certificate is called car.crt
when you are building a normal retrofit request it is usually something like this
You are developing an application with its own backend server and you want to create a secure SSL connection from your Android app with a self signed certificate
You are
- Using retrofit 2
- Have the self signed certificate and its root CA, if you don't then this link can help you
- You have to do it for every device
- You force the user to have a pattern, pin or password lock
Solution
First we are going to add the certificate CA to the "res\raw" folder in this case the certificate is called car.crt
when you are building a normal retrofit request it is usually something like this
_retrofit = new Retrofit.Builder() .baseUrl(CustomService.API_URL) .addConverterFactory(GsonConverterFactory.create()) .build();
we are going to change that a little bit, by doing the following
we are going to read the certificate and then we are going to add it to a keystore same as in Android developer and then create an OkHttpClient and return it
private static OkHttpClient getHttpClient(Context context){ try { // Load CAs from an InputStream // (could be from a resource or ByteArrayInputStream or ...) CertificateFactory cf = CertificateFactory.getInstance("X.509"); // get InputStream for the certificate InputStream caInput = context.getResources().openRawResource(R.raw.car); Certificate ca; ca = cf.generateCertificate(caInput); System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); // 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 sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, tmf.getTrustManagers(), null); final OkHttpClient client; client = new OkHttpClient.Builder() .sslSocketFactory(sslcontext.getSocketFactory()) .build(); caInput.close(); return client; } catch (Exception e) { return null; } }
You can now use retrofit to create any request over an Https connection. please comment or contact me in case you have something to add or found any bugs.Now when you are building your retrofit object you are just going to add an extra line
_retrofit = new Retrofit.Builder() .client(getHttpClient(context)) .baseUrl(CustomService.API_URL) .addConverterFactory(GsonConverterFactory.create()) .build();