Resolving Java SSLHandshakeException for Third‑Party PDF Retrieval by Installing Certificates and Using Trust Managers
This guide explains how to troubleshoot a Java SSLHandshakeException caused by an untrusted third‑party HTTPS endpoint when fetching PDF files, covering certificate installation, trustStore configuration, and a custom TrustManager solution to bypass verification.
In the morning the team discovered that a feature stopped working because a third‑party interface switched from HTTP to HTTPS, resulting in a javax.net.ssl.SSLHandshakeException due to the JVM not trusting the target site's certificate.
The error stack trace shows the SSL handshake failure, and the root cause is that the default JVM trust store does not contain the new certificate.
First, the author tried to manually install the server certificate using the InstallCert.java utility from GitHub, compiling it with javac InstallCert.java and running java InstallCert www.example.com to generate a jssecacerts file, which is then placed into the JDK's lib/security directory and the JVM is restarted.
However, this approach is cumbersome for Docker‑based test environments and production, prompting the search for alternative solutions.
Two additional methods were considered:
1. Set the system property javax.net.ssl.trustStore to point to the custom jssecacerts file. 2. Launch the Java application with -Djavax.net.ssl.trustStore=path/to/jssecacerts -Djavax.net.ssl.trustStorePassword=changeit .
The first method succeeded in setting the property but still failed to load the certificate, likely due to path or permission issues.
Finally, the author adopted a third approach: bypass SSL verification entirely for this specific PDF‑fetching request. The solution creates a custom TrustAnyTrustManager that implements X509TrustManager with empty verification methods, and a TrustAnyHostnameVerifier that always returns true . The code establishes an HttpsURLConnection , injects the custom SSLContext , and reads the PDF stream.
URL console = new URL(url);
HttpURLConnection conn = (HttpURLConnection) console.openConnection();
if (conn instanceof HttpsURLConnection) {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());
((HttpsURLConnection) conn).setHostnameVerifier(new TrustAnyHostnameVerifier());
}
conn.connect();
InputStream inputStream = conn.getInputStream();
PdfReader pdfReader = new PdfReader(inputStream);
inputStream.close();
conn.disconnect(); private static class TrustAnyTrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; }
}
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) { return true; }
}This solution effectively resolves the SSL issue for the PDF retrieval, providing a practical workaround when managing certificates is not feasible.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.