javax.net.ssl.SSLHandshakeException от IBM Watson помощник API - PullRequest
0 голосов
/ 14 марта 2019

При попытке подключиться к IBM Watson API появляется следующая ошибка:

java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at com.ibm.watson.developer_cloud.service.security.IamTokenManager.callIamApi(IamTokenManager.java:190)
        at com.ibm.watson.developer_cloud.service.security.IamTokenManager.requestToken(IamTokenManager.java:108)
        at com.ibm.watson.developer_cloud.service.security.IamTokenManager.getToken(IamTokenManager.java:78)
        at com.ibm.watson.developer_cloud.service.WatsonService.setAuthentication(WatsonService.java:375)
        at com.ibm.watson.developer_cloud.service.WatsonService.createCall(WatsonService.java:206)
        at com.ibm.watson.developer_cloud.service.WatsonService.createServiceCall(WatsonService.java:240)
        at com.ibm.watson.developer_cloud.assistant.v2.Assistant.createSession(Assistant.java:107)
        [...]
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:128)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
        at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:279)
        at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:181)
        at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
        at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:318)
        at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:282)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:167)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)

[...]

Это код Java, который пытается инициировать вызов API:

// Init assistant
IamOptions imaOptions = new IamOptions.Builder()
    .apiKey(API_KEY)
    .build();

assistant = new Assistant("2019-03-13", imaOptions);
assistant.setEndPoint(END_POINT_FRA);

// Create session
CreateSessionOptions options = new CreateSessionOptions.Builder(ASSISTANT_ID).build();
ServiceCall<SessionResponse> session = assistant.createSession(options);

Исключение выдается в последней строке. Интересно, что я могу прекрасно подключиться, когда я запускаю это через автономный модульный тест. Только когда я пытаюсь подключиться из серверного приложения, я получаю эту ошибку SSL.

Я уже пробовал следующее:

  • импортировать все необходимые сертификаты SSL в приложения * 1015 доверенных *

  • установить системное свойство для поддержки TLS 1.2 до TLS 1.1

  • проверил, что установлены полные файлы политики JCE (как часть Java 11, какая у меня версия)

  • использовал nmap для проверки наборов шифров сервера и проверки их поддержки JDK (nmap -sV --script ssl-enum-ciphers -p 443 wildcard.bluemix.net)

Я также прочитал и следовал этим статьям:

Получено фатальное предупреждение: handshake_failure через SSLHandshakeException

https://confluence.atlassian.com/jirakb/sslhandshakeexception-received-fatal-alert-handshake_failure-due-to-no-overlap-in-cipher-suite-943544397.html

Я немного растерялся. Любые идеи, что может быть причиной проблемы рукопожатия SSL или как я мог бы диагностировать это дальше?

==== Обновление ====

После изучения этой темы, я думаю, мне удалось ее изолировать. Кажется, это настоящая ошибка в Java 11.0.1, которая также присутствует в 11.0.2. Основная причина в том, что Java 11 (OpenJDK) не очень хорошо работает с TLSv1.3, как описано здесь: https://webtide.com/openjdk-11-and-tls-1-3-issues/ и в отчете об ошибке здесь https://bugs.openjdk.java.net/browse/JDK-8213202

Теперь проблема в том, как отключить TLSv1.3. Я уже пробовал решения, представленные здесь https://blogs.oracle.com/java-platform-group/jdk-8-will-use-tls-12-as-default и здесь https://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html (протоколы и свойства), но по некоторым причинам это отключение не действует в моем случае. Мой код использует org.apache.http.impl.client.ClosableHttpClient, и Builder не позволяет мне получить доступ к базовому SSLConnectionSocketFactory (где я мог бы отключить TLSv1.3). Итак, остается вопрос: как я могу отключить TLSv1.3 в этом конкретном параметре?

(PS: проблема также возникает при попытке доступа к API Google NL и Vision - language.googleapis.com и vision.googleapis.com)

1 Ответ

0 голосов
/ 01 апреля 2019

В JDK 11.0.1 и 11.0.2 есть ошибка, связанная с TLSv1.3.Эту версию протокола TLS необходимо отключить, установив следующее системное свойство:

-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2

Предположительно, эта ошибка будет исправлена ​​в выпуске JDK 11.0.3., Выход которого ожидается в середине апреля.19.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...