I have a .p12 certificate file, and I use the SSL Converter to convert it to a .pem certificate file. Then I use that pem certificate file in my android code like this:
OkHttpClient okHttpClient = new OkHttpClient();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream instream = context.getResources().openRawResource(R.raw.pem_certificate);
Certificate ca;
ca = cf.generateCertificate(instream);
KeyStore kStore = KeyStore.getInstance(KeyStore.getDefaultType());
kStore.load(null, null);
kStore.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(kStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
} catch (CertificateException
| KeyStoreException
| NoSuchAlgorithmException
| IOException
| KeyManagementException e) {
e.printStackTrace();
}
baseURL = endpoint;
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(baseURL)
.setClient(new OkClient(okHttpClient))
.build();
service = restAdapter.create(DishService.class);
But this code doesn't work. It was failed at the line "ca = cf.generateCertificate(instream);" with CertificateException message.
The answer from Jay got me started, but I got this error: Trust anchor for certification path not found
I managed to import the p12 certificate I had into a keystore using the KeyTool command.
More specifically:
Step 1. Generate a new keystore with a default certificate and then delete it
Step 2. Import the certificate
Step 3: I then used the following code to load the SSLContext:
Thanks to the code here: https://chariotsolutions.com/blog/post/https-with-client-certificates-on/
Maybe you have a problem in R.raw.pem_certificate...
1) Try to get a raw public certificate from server using openssl : openssl s_client -connect {HOSTNAME}:{PORT} -showcerts
(please look here for details: https://superuser.com/questions/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file)
2) How to setup Retrofit2 with a custom SSL sertificate https://adiyatmubarak.wordpress.com/tag/add-ssl-certificate-in-retrofit-2/
or Retrofit1: https://number1.co.za/use-retrofit-self-signed-unknown-ssl-certificate-android/
PS: it works for me, please don't convert PEM file to BKS.
}
After reading lots of post, blogs and gist I finally found a way. This works for me.
Step1: Put your security certificate inside raw directory like src/main/res/raw/client_certificate.cer
Step2: Create a SSLContext object with this certificate like
Step3: Add the created SSLContext object to your OkHttpClient builder.
Step4: Set the OkHttpClient builder to retrofit client like.
Here is complete implementation for all above mentioned steps in RetrofitManager.java file.
RetrofitManager.java