1. Overview
In this tutorial, we'll see how to create and configure an OkHttpClient to trust all certificates.
Take a look at our articles about OkHttp for more specifics on the library.
2. Maven Dependency
Let's start by adding the OkHttp dependency to our pom.xml file:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.2</version>
</dependency>
3. Use a Normal OkHttpClient
First, let's take a standard OkHttpClient object and call a web page with an expired certificate:
OkHttpClient client = new OkHttpClient.Builder().build();
client.newCall(new Request.Builder().url("https://expired.badssl.com/").build()).execute();
The stack trace output will look like:
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
Now, let's see the error received when we try another website with a self-signed certificate:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
And let's try a website with a wrong-host certificate:
Hostname wrong.host.badssl.com not verified
As we see, by default, OkHttpClient will throw errors if calling sites to have bad certificates. So next, we'll see how to create and configure an OkHttpClient to trust all certificates.
4. Set Up an OkHttpClient to Trust All Certificates
Let's create our array of TrustManager containing a single X509TrustManager that disables the default certificate validations by overriding their methods:
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
We'll use this array of TrustManager to create an SSLContext:
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
And then, we'll use this SSLContext to set the OkHttpClient builder's SSLSocketFactory:
OkHttpClient.Builder newBuilder = new OkHttpClient.Builder();
newBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]);
newBuilder.hostnameVerifier((hostname, session) -> true);
We also set the new Builder‘s HostnameVerifier to a new HostnameVerifier object whose verification method always returns true.
Finally, we can get a new OkHttpClient object and call the sites with bad certificates again without any error:
OkHttpClient newClient = newBuilder.build();
newClient.newCall(new Request.Builder().url("https://expired.badssl.com/").build()).execute();
5. Conclusion
In this short article, we've seen how to create and configure an OkHttpClient to trust all certificates. Of course, trusting all certificates is not recommended. However, there may be some cases where we will need it.
The complete code for this article is available over on GitHub.