javax.net.ssl.SSLHandshakeException:收到致命警报:google-client-api 的握手失败

Cro*_*roy 3 google-calendar-api ssl-certificate google-client tls1.2 java-11

我正在尝试使用 google-client-api 获取 google-calendar 但遇到以下错误:

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:308)
    at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:285)
    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 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.getOutputStream0(HttpURLConnection.java:1362)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1337)
    at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:246)
    at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:113)
    at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:84)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1012)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:322)
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:346)
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:398)
    at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:494)
    at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:880)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:541)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:474)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:591)
    at org.springframework.batch.core.listener.CompositeJobExecutionListener.beforeJob(CompositeJobExecutionListener.java:73)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:298)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:127)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
    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)
Run Code Online (Sandbox Code Playgroud)

下面是导致错误的代码片段:

calendarList = getGoogleCalendarServiceInstance(googleCredential).calendarList().list()
                .setMaxResults(MAX_RESULTS).setPageToken(pageToken).execute();
Run Code Online (Sandbox Code Playgroud)

build.gradle如下:

#!groovy

ext {
    googleApiVersion = '1.17.0-rc'
    googleCalendarApiVersion = 'v3-rev74-1.17.0-rc'
}

dependencies {
    compile group: 'com.google.api-client', name: 'google-api-client', version: "${googleApiVersion}"
    compile group: 'com.google.http-client', name: 'google-http-client-jackson2', version: "${googleApiVersion}"
    compile group: 'com.google.apis', name: 'google-api-services-calendar', version: "${googleCalendarApiVersion}"
}
Run Code Online (Sandbox Code Playgroud)

请注意确定是证书导致了错误还是我缺少某些依赖项?请建议。

注意:我们已从 java-8 迁移到 java-11,目前使用捆绑包 jre。

Cro*_*roy 8

发布答案,因为它可能对面临相同问题的其他人有所帮助。

该问题的产生是因为“EC 密码套件丢失”。ClientHello 之后握手立即失败,因为服务器不支持客户端发送的任何密码套件。

我在 https://bugs.openjdk.java.net/browse/JDK-8221674找到了这个解决方案

以下更改解决了我的问题:

在 add-modules 中指定提供者:

%JAVA_HOME%\bin\jlink.exe --module-path "mods" --add-modules=test,jdk.crypto.ec --output jre
Run Code Online (Sandbox Code Playgroud)