Поскольку OpenJDk Java 11 получает javax. net .ssl.SSLHandshakeException: получено фатальное предупреждение: handshake_failure - PullRequest
1 голос
/ 28 апреля 2020

Недавно обновили приложение с Oracle Java 9 до AdoptJDk 11.0.6, и теперь я вижу ошибки в виде этого кода:

 public static String convertWikidataUrl(String wikidataUrl)
    {
        String qPage  = wikidataUrl.substring(wikidataUrl.lastIndexOf('/') + 1);
        String apiUrl = WIKIDATA_IMAGE_API_URL + qPage;
        try
        {
            URL url = new URL(apiUrl);
            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
            int responseCode = uc.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK)
            {
                MainWindow.logger.severe(":ResponseCode:"+responseCode);

            }

            //Everything ok so continue
            BufferedInputStream bis = new BufferedInputStream(uc.getInputStream());
            JAXBContext jc = getWikidataInitialContext();
            Unmarshaller um = jc.createUnmarshaller();
            Api api = (Api) um.unmarshal(bis);
            if(api.getClaims()!=null
                    && api.getClaims().getProperty()!=null
                    && api.getClaims().getProperty().getClaim()!=null
                    && api.getClaims().getProperty().getClaim().getMainsnak()!=null
                    && api.getClaims().getProperty().getClaim().getMainsnak().getDatavalue()!=null)
            {
                return api.getClaims().getProperty().getClaim().getMainsnak().getDatavalue().getValue();
            }
            else
            {
                return null;
            }
        }
        catch (JAXBException e)
        {
            MainWindow.logger.log(Level.SEVERE, e.getMessage(), e);
        }
        catch (MalformedURLException mue)
        {
            MainWindow.logger.log(Level.SEVERE, mue.getMessage(), mue);
        }
        catch (Exception ex)
        {
            MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex);
        }
        return null;
    }

завершается с ошибкой:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)
    at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:291)
    at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:180)
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
    at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1151)
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1062)
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
    at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
    at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
    at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
    at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:334)
    at com.jthink.songkong.analyse.musicbrainz.WikipediaImage.convertWikipediaUrl(WikipediaImage.java:49)
    at com.jthink.songkong.analyse.musicbrainz.ArtistArtwork.findArtistImageLink(ArtistArtwork.java:54)
    at com.jthink.songkong.analyse.musicbrainz.ArtistArtworkOnlineLookup.call(ArtistArtworkOnlineLookup.java:63)
    at com.jthink.songkong.analyse.musicbrainz.ArtistArtworkOnlineLookup.call(ArtistArtworkOnlineLookup.java:26)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

Проблема была замечена на Windows, но может возникать и на других платформах

Ошибка определенно связана с изменением JRE, но я не знаю, переходит ли проблема с Java 9 к 11 или переходу от Oracle к AdoptJdk, как мне решить эту проблему?

Обновление

  1. Проблема не возникает на MacOS с использованием 11.0. 6
  2. Вкл. Windows Обновление с 11.0.6 до 11.0.7 не имело никакого эффекта
  3. Вкл. Windows Добавление -Dhttps.protocols = TLSv1.1, TLSv1.2 (к отключенному TLS1 .3 поддержка) устраняет проблему.
  4. Возможно, версия этой ошибки https://bugs.openjdk.java.net/browse/JDK-8206923

1 Ответ

2 голосов
/ 06 мая 2020

Клиент не может открыть соединение с сервером, потому что он, вероятно, не поддерживает те же версии или настройки TLS.

Попробуйте запустить приложение с:

  • -Dhttps.protocols=TLSv1.2
  • -Dhttps.protocols=TLSv1.3
  • -Dhttps.protocols=TLSv1.0

TLSv1.2 (2008) - это поддерживаемая в настоящее время версия TLS, которая развернута повсеместно и поддерживается где угодно. Это безопасное значение по умолчанию и то, что нужно для того, чтобы вещи просто работали.

TLSv1.3 (2018) - готовящаяся версия. Он медленно внедряется везде (веб-серверы, приложения, балансировщики нагрузки, CDN и т. Д. c ...). Переход должен быть плавным, но это не совсем так, ни одно программное обеспечение не является идеальным с первой попытки, и появляются некоторые ошибки и несовместимости. JDK 11 представляет TLSv1.3 и пытается использовать его по умолчанию, что не очень хорошо go с учетом ошибки, поэтому обходной путь должен принудительно использовать вместо него TLSv1.2.

Есть Сложные крайние случаи, если вы используете TLS для аутентификации сертификата клиента , часто используется в корпоративных системах, работающих с высокочувствительной информацией, такой как банковские API. TLS 1.3 изменил способ аутентификации клиента, поэтому программное обеспечение клиента и сервера, вероятно, необходимо обновить, чтобы оно вообще могло работать. HTTP / 2 нарушает аутентификацию клиента по замыслу, RF C ожидает согласования решения, в то же время используется HTTP / 1.1.

TLSv1.0 (1999) является устаревшей версией, которая запрещена использование и удалено в последних версиях библиотеки (OpenSSL 1.1.x, JDK 11 и др. c ...). С 2020 года можно столкнуться с этим, если вы работаете с устаревшими корпоративными java приложениями, которые не обслуживались годами. Они действительно должны быть обновлены.

...