3

I am getting the error handshake_failure when using jersey client to call api with HTTPS. If the site is hosted as HTTP then it is working fine. I have turned off the server certificate validity check as well when using HTTPS.

@Test
public void GetMember2(){
    try{
        System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");

        Date today1 = new Date(); // default window is 1 hour
        String stringToday1 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US).format(today1);

        Client client = Client.create(configureClient());

        WebResource webResource = client.resource("https://test.abcd.net/Members/72771583886/promotions?startDate=12122015");

        ClientResponse response = webResource.accept("application/xml")
                .type("application/xml")
                .header("Date", stringToday1)
                .get(ClientResponse.class);

        if (response.getStatus() != 200) {
           throw new RuntimeException("Failed : HTTP error code : "
            + response.getStatus());
        }

        String output = response.getEntity(String.class);

        System.out.println("Output from Server .... \n");
        System.out.println(output);

      } catch (Exception e) {
        e.printStackTrace();
      }
}

public static ClientConfig configureClient() {
    TrustManager[ ] certs = new TrustManager[ ] {
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkServerTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {
                }
                public void checkClientTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {
                }
            }
    };
    SSLContext ctx = null;
    try {
        ctx = SSLContext.getInstance("TLS");
        ctx.init(null, certs, new SecureRandom());
    } catch (java.security.GeneralSecurityException ex) {
    }
    HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

    ClientConfig config = new DefaultClientConfig();
    try {
        config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
            new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            }, 
            ctx
        ));
    } catch(Exception e) {
    }

    return config;
}

Error: com.sun.jersey.api.client.ClientHandlerException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:155) at com.sun.jersey.api.client.Client.handle(Client.java:652) at com.sun.jersey.api.client.WebResource.handle(WebResource.java:682) at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:509) at Frameworks.Prototype2.GetLoyaltyMember2(Prototype2.java:106) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source)

Iłya Bursov
  • 23,342
  • 4
  • 33
  • 57
user6332513
  • 31
  • 1
  • 3
  • The following code perfectly work in C#/Visual Studio when I call the api with HTTPS connection. I am not able to find similar things in Java. //Turn off check for server certificate validity ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; – user6332513 May 18 '16 at 20:37
  • You can get this error from older JDK versions too (presumably from different/older TLS support included in the JDK). For example, identical code executed with 1.7 I get this error, but 1.8 I do not. – Kevin Hooke Aug 06 '18 at 18:22

3 Answers3

2

Temporarily turn on debugging of the Java networking library to see what sort of SSL error(s) you're getting: -Djavax.net.debug=all

Eric Kramer
  • 192
  • 2
  • 7
0

Handshake can fail for various reasons and not only for certificate validation problems. It could be for:

  • Not sharing same cipher suites
  • Not sharing SSL versions
  • Certificate validation
  • Intent to change TLS version
  • Others

The best way to figure out what your problem is is to install Wireshark and see the handshake messages. Then based on the SSL alert message sent from server to client you can have more information on the SSL handshake failure, where specifically it happened.

This link might also help: Received fatal alert: handshake_failure through SSLHandshakeException

Community
  • 1
  • 1
rodolk
  • 5,606
  • 3
  • 28
  • 34
  • The following code perfectly work in C#/Visual Studio when I call the api with HTTPS connection. I am not able to find similar things in Java. //Turn off check for server certificate validity ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11; – user6332513 May 18 '16 at 20:20
  • @user6332513, OK just use wireshark or other tool to understand why is the SSL alert. What alert type it is. – rodolk May 19 '16 at 00:29
0

From the oracle website download jce_policy-8.zip and extract it to obtain the following 2 JAR-files.

local_policy.jar US_export_policy.jar

Update the above 2 policies in your JVM i.e., in my case /Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/lib/security

And it should work.

sebix
  • 2,943
  • 2
  • 28
  • 43