1
votes

I am trying to make a connection to a secure server & the java code fails with the SSLHandshakeException. When I enabled -Djavax.net.debug=all I got the below error:

main, RECV TLSv1.2 ALERT: fatal, handshake_failure

%% Invalidated: [Session-1, SSL_RSA_WITH_3DES_EDE_CBC_SHA] main, called closeSocket()

main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

I have already searched enough & tried: -Dhttps.protocols & -Dhttps.cipherSuites options & none of them seem to work.

I also checked for:

socketfactory.getDefaultCipherSuites() which lists the cipher stated in the error.

I checked with the

openssl s_client -connect url:443

but it throws an error:

verify error:num=20:unable to get local issuer certificate

verify return:0

58555:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.30.1/src/ssl/s3_pkt.c:1145:SSL alert number 40

58555:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:/SourceCache/OpenSSL098/OpenSSL098-52.30.1/src/ssl/s23_lib.c:185:

Appreciate quick help & direction on this one.

I am doing this with spring ws where I am creating a HttpClient of my own as this connection requires a server keystore for a connection. Following is the code that I am using:

    public NewHttpClient(KeyStore keyStore, String pwd, Integer maxTotal, Integer defaultMaxPerRoute) throws KeyManagementException, UnrecoverableKeyException,
NoSuchAlgorithmException, KeyStoreException {
    HttpClientBuilder builder = HttpClientBuilder.create();
    SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, pwd.toCharArray()).build();
    builder.setSSLContext(sslContext);
    SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(sslContext);
    builder.setSSLSocketFactory(sslConnectionFactory);
    Registry<ConnectionSocketFactory> schemeRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", PlainConnectionSocketFactory.getSocketFactory())
            .register("https", SSLConnectionSocketFactory.getSocketFactory()).build();
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(schemeRegistry);
    connectionManager.setMaxTotal(maxTotal);
    connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
    builder.setConnectionManager(connectionManager);
    customHttpClient = builder.build();
}

UPDATE 1: When I am using the keystore from SOAP-UI, it simply works without any issue. Its only a problem in the java approach!

UPDATE 2: I have tried with 3 JVMs 6, 7 & 8 but the issue persists. Also, I tried to create an SSL connection from a plain java code instead of spring & was able to successfully do a handshake without any issues.

1
in java which JVM are you using? I had similar issue on JVM 6; when I used Oracle JDK 7 all worked pretty good... same code on JVM 6 generated similar errorAngelo Immediata
I am using 8. But I also tried with 6 & 7 with JCE. Its the same error!Karthik

1 Answers

1
votes

I saw that this was a spring issue based on my update 2. So I changed my approach to use the

org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender

& voila it worked without any issues.

I had to import the above class from a new maven jar:

  <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-support</artifactId>
        <version>2.2.0.RELEASE</version>
    </dependency>