2
votes

I'm receiving the ever so popular "SSLHandShakeException".

I'm running a java client using IntelliJ that is designed to handle web service requests/responses. We connect to server through a set of credentials and a url and pass in a request file.

What I've done

  1. Verified the URL being constructed works in a browser.

  2. Added the certificate to the trust store using these instructions, Keytool Instructions

  3. Verified the correct JRE is being used for the truststore.

  4. I'm using an httpClient object. I instantiate the object as follows,

    private void initConnection()
    {
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(new AuthScope(this.target.getHostName(), this.target.getPort()), new UsernamePasswordCredentials(this.userid, this.password));
    
        this.httpClient = HttpClients.custom().setDefaultCredentialsProvider(credsProvider).build();
    
        // Be able to deal with basic auth. Generate BASIC scheme object and
        // add it to the local auth cache
    
        BasicScheme basicScheme = new BasicScheme(); // we throw an error here
        this.authCache.put(this.target, basicScheme);
        localContext = HttpClientContext.create();
        localContext.setAuthCache(this.authCache);
    }
    
    1. The execute for this object is as follows which is also the code throwing the error,

      responseNode = this.httpClient.execute(getTarget(), httpRequest, responseHandler);
      
    2. I've tried forcing the trust store in the process as follows,

      System.setProperty("javax.net.ssl.trustStore", "....Common\JRE\lib\security\cacerts"); System.setProperty("javax.net.ssl.trustStorePassword","changeit");

    3. Works just fine against http when SSL is not involved.

Other then that I'm not an expert with SSL. I've performed quite a bit of digging and I am hoping someone out there has an idea. I'm certainly open to having not installed the cert properly (dozen times) or possibly I need to add some more code to correctly configure my objects. If there is missing information I would be happy to provide it!

Thanks well in advance.

2
You might need to update your path to cacerts by escaping the escape characters. Have you tried printing the value of java.net.ssl.trustStore after it is set?Andy Senn
The characters are being escaped, Stackoverflow is being helpful and removing them. I cannot say that I have printed the value. Let me give that a go. Ideally I do not want to have to include point 6. Its a work around.Bryan Harrington
Please post the entire message and stack trade, and fix your meaningless title.user207421

2 Answers

1
votes

Having had to deal with a number of SSL issues in Java clients myself I understand the frustration with the lack of useful detail in the error messages you are experiencing. Here are a few things you can try and verify.

  1. That the server and the client can agree on the SSL version.

Like many protocols the SSL/TLS protocol has several versions out there. TLS implementations are practically always backwards compatible, but since the earlier versions of the protocol are considered insecure many servers and clients will not accept earlier version.

  1. Hostname mismatch.

The TLS protocol specifies that even though a server's certificate might be trusted the certificate itself the common name of the certificate must match the hostname of the server. For example if a server at www.microsoft.com provided a www.google.com certificate the client would not accept the connection. This issue tends to be a big problem when people are connecting to internal servers, but not so much a problem when connecting to public servers. There is a pretty simple way to disable hostname verification with a custom SSL factory.

1
votes

By using the custom HttpClient it is not looking at the system trust store by default from HttpClientBuilder docs:

When a particular component is not explicitly set this class will use its default implementation. System properties will be taken into account when configuring the default implementations when useSystemProperties() method is called prior to calling build().

Try using

HttpClients.custom().setDefaultCredentialsProvider(credsProvider).useSystemProperties().build();