Apache httpclient: Reading SSL with self-signed certificates

Posted by {"name"=>"Palash Ray", "email"=>"paawak@gmail.com", "url"=>"https://www.linkedin.com/in/palash-ray/"} on October 28, 2017 · 1 min read

When we try to access SSL sites secured with self-signed certificates using apache httpclient, we get the below exception:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

We will attempt to work-around this problem. First, we will run a docker image that has a Tomcat8 with a self-signed certificate (refer to http://palashray.com/tomcat-8-ssl-configuration-with-self-signed-certificate/).

docker pull paawak/self-signed-tomcat8
docker run -d -p 9090:8443 paawak/self-signed-tomcat8

Check that the link is accessible: https://localhost:9090/docs/security-howto.html
The below code will ignore the self-signed certificate security issue and allow us to access this site:

public Response connectUnTrusted(String selfSignedUrl) throws IOException {
TrustStrategy trustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
};
SSLContext sslContext;
try {
sslContext = new SSLContextBuilder().loadTrustMaterial(null, trustStrategy).build();
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
throw new RuntimeException(e);
}
CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSSLContext(sslContext).build();
// optional cookie store
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("foo", "value");
cookie.setDomain("localhost");
Executor executor = Executor.newInstance(httpClient).use(cookieStore);
Request request = Request.Post(selfSignedUrl);
return executor.execute(request);
}

Here are the Maven dependencies:


org.apache.httpcomponents
httpclient
${httpclient.version}


org.apache.httpcomponents
httpmime
${httpclient.version}


org.apache.httpcomponents
fluent-hc
${httpclient.version}

The sources for this example can be found here:
https://github.com/paawak/blog/tree/master/code/apache-http-client/