The problem
So, I have a server I need to connect to that is using an old, deprecated certificate. If I try to connect to it with Apache HttpClient
, I get SSLException: Received fatal alert: close_notify
. The client itself does not need to be reusable for other servers, but the builder code must be able to.
My less-than-ideal workaround
I have worked around this by setting a fallback TLS protocol, but it isn't ideal because it adds another request. There must be a more elegant way than this:
URL url = new URL("https://...");
SSLContextBuilder sslContextBuilder = SSLContexts.custom();
try {
url.openConnection().connect();
} catch (SSLException e) {
sslContextBuilder.useProtocol("TLSv1");
}
I have also tried
I have also tried creating a custom SSLConnectionSocketFactory
, but apache ignores TLSv1
if TLSv1.2
is included as an option.
SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(
SSLContext.getDefault(),
new String[] { "TLSv1.2", "TLSv1" },
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
Reflection
In essence, I suppose that the base problem is that the remote server uses a deprecated cipher suite. I could pass in all the cipher suites I want to support into the SSLConnectionSocketFactory
, but there are a lot, and Sun has hidden away the full listing behind private classes.