4

I'm trying to comunicate with an URI that uses TLS 1.2 using java jdk 1.6.30 and I tried to setup BouncyCastle provider on my system as TLS 1.2 is not suported by default on java jdk 1.6.30 I also instaled the certificate on my local machine but I'm receiving the following error:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1806)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:986)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
    at main.main(main.java:22)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

The code I'm using is as follows:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.net.*;
import java.security.Security;

public class main {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static void main(String[] args) throws Exception {
        final URL url = new URL("URL");
        final String postData = "POST_DATA";
        final byte[] postDataBytes = postData.getBytes("UTF-8");
        final HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        httpURLConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
        httpURLConnection.setDoOutput(true);
        httpURLConnection.getOutputStream().write(postDataBytes);
        httpURLConnection.getInputStream();
        System.out.println("OK");
    }
}

I tried to google but I haven't found any solution (TLS 1.2 + Java 1.6 + BouncyCastle, Received fatal alert: handshake_failure with Tomcat, etc).

Is there anything I can try to trust the certificate?

Thanks in advance

Community
  • 1
  • 1
user3698770
  • 95
  • 2
  • 9
  • 1
    as far as i know you should create keytool with certificate "keytool -import -alias foo -file C:/Users/xxx/xxxx.cer -keystore keystoreName" – newuserua_ext Jan 14 '16 at 12:15
  • Is it absolutely required that you use Java 6? Java 6 does not have built-in support for TLSv1.2. It would be much easier with Java 7 or newer, since these do support TLSv1.2. – Jesper Jan 14 '16 at 12:35
  • I've added the certificate to java using keytool. On the other hand, it's required that I use Java 6... If I can decide I will use Java 8 :) – user3698770 Jan 14 '16 at 12:45
  • lest add this part of code in your before open url connection and see result is changing or not; String javaHomePath = System.getProperty("java.home"); String keystore = "C:\\.keystore"; String storepass = "changeit"; String storetype = "JKS"; String[][] props = { { "javax.net.ssl.trustStore", keystore, }, { "javax.net.ssl.keyStore", keystore, }, { "javax.net.ssl.keyStorePassword", storepass, }, { "javax.net.ssl.keyStoreType", storetype, }, }; for (int i = 0; i < props.length; i++) System.getProperties().setProperty(props[i][0], props[i][1]); – newuserua_ext Jan 14 '16 at 14:03
  • I just tried with this code and the result is the same also using "keytool -list" I can see the certificate properly imported. I understand that your code is to check if I'm using the proper keystore. – user3698770 Jan 14 '16 at 14:12
  • I have the same problem using Java 1.6 and haven't found a solution jet. The problem is that I have Java 1.6 installed as part of Oracle database 11.4 and Java can't be upgraded. In my case, I have Java stored procedures which are communicating with a remote server (that server supported TLS1.0 - TLS1.2, but now they have disabled TLS1.0 and TLS1.1 protocol). If I use BouncyCastle as you I get the same error: org.bouncycastle.crypto.tls.TlsFatalAlertReceived: handshake_failure(40) – Ferguson Mar 21 '18 at 11:24

1 Answers1

0

You can try this code, I used BouncyCastle 1.60 and Java 1.6_65

BouncyCastleJsseProvider provider = new BouncyCastleJsseProvider(new BouncyCastleProvider());
SSLContext context = SSLContext.getInstance("TLS", provider);
TrustAllX509TrustManager manager = new TrustAllX509TrustManager();

context.init(null, new X509TrustManager[] { manager }, new SecureRandom());

URL url = new URL("https://stackoverflow.com:443");

HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(context.getSocketFactory());

connection.connect();

Actually, one of the latest versions of java 1.6 supports TLS 1.2 https://www.oracle.com/technetwork/java/javase/overview-156328.html#R160_121

user3337952
  • 49
  • 1
  • 4