Java 1.6 TLS 1.2 рукопожатие_сбой

Я пытаюсь связаться с URI, который использует TLS 1.2, используя java jdk 1.6.30, и я попытался настроить провайдера BouncyCastle в своей системе, поскольку TLS 1.2 по умолчанию не поддерживается в java jdk 1.6.30. Я также установил сертификат на свой локальная машина, но я получаю следующую ошибку:

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)

Код, который я использую, выглядит следующим образом:

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");
    }
}

Я пытался гуглить, но не нашел решения (TLS 1.2 + Java 1.6 + BouncyCastle, Получено фатальное предупреждение: handshake_failure with Tomcat , и т.д).

Есть ли что-нибудь, что я могу попробовать доверять сертификату?

заранее спасибо


person user3698770    schedule 14.01.2016    source источник
comment
насколько я знаю, вы должны создать keytool с сертификатом keytool -import -alias foo -file C:/Users/xxx/xxxx.cer -keystore keystoreName   -  person newuserua_ext    schedule 14.01.2016
comment
Обязательно ли использовать Java 6? В Java 6 нет встроенной поддержки TLSv1.2. Было бы намного проще с Java 7 или новее, так как они поддерживают TLSv1.2.   -  person Jesper    schedule 14.01.2016
comment
Я добавил сертификат в java с помощью keytool. С другой стороны, требуется, чтобы я использовал Java 6... Если я смогу решить, я буду использовать Java 8 :)   -  person user3698770    schedule 14.01.2016
comment
чтобы не добавлять эту часть кода в ваше соединение перед открытым URL-адресом и не видеть, меняется результат или нет; Строка javaHomePath = System.getProperty(java.home); Строковое хранилище ключей = C:\\.keystore; Строка storepass = changeit; Тип хранилища строк = JKS; String[][] props = { { javax.net.ssl.trustStore, хранилище ключей, }, { javax.net.ssl.keyStore, хранилище ключей, }, { javax.net.ssl.keyStorePassword, storepass, }, { javax. net.ssl.keyStoreType, тип хранилища, }, }; for (int i = 0; i ‹ props.length; i++) System.getProperties().setProperty(props[i][0], props[i][1]);   -  person newuserua_ext    schedule 14.01.2016
comment
Я только что попробовал этот код, и результат тот же, что и с помощью keytool -list, я вижу, что сертификат правильно импортирован. Я понимаю, что ваш код должен проверить, использую ли я правильное хранилище ключей.   -  person user3698770    schedule 14.01.2016
comment
У меня такая же проблема с использованием Java 1.6, и я не нашел решения. Проблема в том, что у меня установлена ​​Java 1.6 как часть базы данных Oracle 11.4, и Java не может быть обновлена. В моем случае у меня есть хранимые процедуры Java, которые взаимодействуют с удаленным сервером (этот сервер поддерживал TLS1.0 - TLS1.2, но теперь они отключили протоколы TLS1.0 и TLS1.1). Если я использую BouncyCastle, как и вы, я получаю ту же ошибку: org.bouncycastle.crypto.tls.TlsFatalAlertReceived: handshake_failure(40)   -  person Ferguson    schedule 21.03.2018


Ответы (1)


Вы можете попробовать этот код, я использовал BouncyCastle 1.60 и 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();

Собственно, одна из последних версий java 1.6 поддерживает TLS 1.2 https://www.oracle.com/technetwork/java/javase/overview-156328.html#R160_121

person user3337952    schedule 22.05.2019