JDK8 -> JDK10: сбой при создании пути PKIX: SunCertPathBuilderException: невозможно найти действительный путь сертификации для запрошенной цели - PullRequest
0 голосов
/ 11 ноября 2018

Задача

  • У меня есть приложение SpringBoot, использующее приложение под названием Launchdarkly, которое использует okhttp
  • Я перехожу с JRE 8 на JRE 10, звонки на другие ресурсы работают, но не удается при звонках, сделанных с использованием okhttp

РЕДАКТИРОВАТЬ : Это может произойти с любым приложением, которое имеет цепочку сертификатов, аналогичную той, которая используется нашим приложением.

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Исключение

Ошибка возникает в этой теме ...

config-server_1  | 2018-11-10T21:25:19,147 67327 | DEBUG | okhttp-eventsource-[] ["okhttp-eventsource-stream-[]-0" {}] Connection problem.
config-server_1  | javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
config-server_1  |  at sun.security.ssl.Alerts.getSSLException(Alerts.java:198) ~[?:?]
config-server_1  |  at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1974) ~[?:?]
config-server_1  |  at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:345) ~[?:?]
config-server_1  |  at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:339) ~[?:?]
config-server_1  |  at sun.security.ssl.ClientHandshaker.checkServerCerts(ClientHandshaker.java:1968) ~[?:?]
config-server_1  |  at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1777) ~[?:?]
config-server_1  |  at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:264) ~[?:?]
config-server_1  |  at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1098) ~[?:?]
config-server_1  |  at sun.security.ssl.Handshaker.processRecord(Handshaker.java:1026) ~[?:?]
config-server_1  |  at sun.security.ssl.SSLSocketImpl.processInputRecord(SSLSocketImpl.java:1137) ~[?:?]
config-server_1  |  at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1074) ~[?:?]
config-server_1  |  at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973) ~[?:?]
config-server_1  |  at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1402) ~[?:?]
config-server_1  |  at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1429) ~[?:?]
config-server_1  |  at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413) ~[?:?]
config-server_1  |  at com.launchdarkly.shaded.okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:281) ~[launchdarkly-client-2.3.2.jar!/:2.3.2]
config-server_1  |  at com.launchdarkly.shaded.okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:251) ~[launchdarkly-client-2.3.2.jar!/:2.3.2]
config-server_1  |  at com.launchdarkly.shaded.okhttp3.internal.connection.RealConnection.connect(RealConnection.java:151) ~[launchdarkly-client-2.3.2.jar!/:2.3.2]
config-server_1  |  at com.launchdarkly.shaded.okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:195) ~[launchdarkly-client-2.3.2.jar!/:2.3.2]
config-server_1  |  at com.launchdarkly.shaded.okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121) ~[launchdarkly-client-2.3.2.jar!/:2.3.2]

Настройка

  • Использование jlink и выбор модулей для создания небольшой JRE
  • У меня только JAVA_HOME установлено ... Не уверен, что нам нужно что-то еще

Сведения о версии Java 10

Устанавливается описанным выше способом

root@e0776fd790e7:/runtime# ls -la /etc/ssl/certs/java/cacerts
-rw-r--r-- 1 root root 177280 Oct 29 16:29 /etc/ssl/certs/java/cacerts
root@e0776fd790e7:/runtime# java -version
openjdk version "10" 2018-03-20
OpenJDK Runtime Environment 18.3 (build 10+46)
OpenJDK 64-Bit Server VM 18.3 (build 10+46, mixed mode)

Keystore установлен

Хранилище ключей java 10 может видеть его

root@17000659d1ec:/runtime# keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 80 entries

Это как описано в https://dzone.com/articles/openjdk-10-now-includes-root-ca-certificates

Попытка

РЕДАКТИРОВАТЬ: см. Мой ответ

1 Ответ

0 голосов
/ 11 ноября 2018

Решение при переходе с JDK 8 на JDK 10

JDK 10

root@c339504909345:/opt/jdk-minimal/jre/lib/security #  keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 80 entries

JDK 8

root@c39596768075:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts #  keytool -cacerts -list
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 151 entries

Действия по исправлению

Я не проверял, какая цепочка сертификатов не является доверенной, но сертификаты URL-адреса сервера действительны ... У cacerts из JDK 10 есть цепочка, которая разорвана на сегодняшний день. Я могу утверждать, что, поскольку загрузка с https://download.java.net/java/GA/jdk10/10/binaries/openjdk-10_linux-x64_bin.tar.gz устанавливается в новом образе Docker.

  • Я удалил сертификат JDK 10 и заменил его на JDK 8
  • Поскольку я создаю Docker Images, я мог быстро сделать это, используя многоэтапные сборки
    • Я строю минимальную JRE, используя jlink как /opt/jdk/bin/jlink \ --module-path /opt/jdk/jmods...

Итак, вот разные пути и последовательность команд ...

# Java 8
COPY --from=marcellodesales-springboot-builder-jdk8 /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts /etc/ssl/certs/java/cacerts

# Java 10
RUN rm -f /opt/jdk-minimal/jre/lib/security/cacerts
RUN ln -s /etc/ssl/certs/java/cacerts /opt/jdk-minimal/jre/lib/security/cacerts
...