How to Fix Java SSLHandshakeException for HTTPS Calls: JCE Update and TLS Version Fix
This guide explains why Java HTTPS requests can fail with an SSLHandshakeException, covering the JCE unlimited‑strength policy replacement and TLS version mismatches, and provides complete code snippets for creating a permissive SSLContext and a pooled HttpClient to resolve the issue.
When automating API tests, an SSLHandshakeException can occur during HTTPS requests. The most common reasons are:
JDK's default Java Cryptography Extension (JCE) policy limits strong encryption algorithms.
The client uses a TLS version that does not match the server (e.g., the server requires TLS 1.2 while the client defaults to an older version).
Fixing the JCE policy
Download the unlimited‑strength JCE policy for the appropriate JDK version and replace the two JAR files in %JAVA_HOME%\jre\lib\security:
JDK 7: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
JDK 8: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
Ensuring the correct TLS version
Inspect the TLS handshake (e.g., with Charles) to verify the server’s protocol. If the server uses TLS 1.2, configure the client to use the same version.
Creating a permissive SSLContext
/**
* Create an SSLContext that trusts all certificates and forces TLSv1.2.
*/
public static SSLContext createIgnoreVerifySSL() {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLSv1.2"); // specify TLS version
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// Trust manager that does not validate certificate chains
X509TrustManager trustManager = new X509TrustManager() {
@Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {}
@Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {}
@Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
};
try {
sslContext.init(null, new TrustManager[] { trustManager }, null);
} catch (KeyManagementException e) {
e.printStackTrace();
}
return sslContext;
}Building a pooled HTTPS client with Apache HttpClient
/**
* Obtain a CloseableHttpClient that uses the permissive SSLContext.
*/
public static CloseableHttpClient getCloseableHttpsClients() {
SSLContext sslContext = createIgnoreVerifySSL();
// Register socket factories for http and https
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslContext))
.build();
// Connection manager with pooling support
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
// Build the custom HttpClient
return HttpClients.custom()
.setConnectionManager(connManager)
.build();
}Alternatively, you can subclass HttpClient and override createDefault() to return a client configured with the custom SSLContext. This approach works for HTTPS endpoints that do not require strict certificate validation.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
