编辑:我试图在我的博客上以更得体的方式格式化问题和接受的答案。

这是最初的问题。

我得到这个错误:

详细消息sun.security.validator.ValidatorException: PKIX路径 构建失败: provider.certpath. suncertpathbuilderexception:不能 找到请求目标的有效认证路径 导致javax.net.ssl.SSLHandshakeException: validatorexception: PKIX路径构建 失败:sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求目标的有效认证路径

我使用Tomcat 6作为web服务器。我在同一台机器上的不同端口的不同Tomcats上安装了两个HTTPS web应用程序。假设App1(端口8443)和App2(端口443)。App1连接到App2。当App1连接到App2时,我得到上述错误。我知道这是一个非常常见的错误,所以在不同的论坛和网站上找到了许多解决方案。我在两个Tomcats的server.xml中有以下条目:

keystoreFile="c:/.keystore" 
keystorePass="changeit"

每个站点都说明了app2给出的证书不在app1 jvm的可信存储区中的相同原因。这似乎也是真的,当我试图在IE浏览器中点击相同的URL,它工作(与升温,有一个问题与此网站的安全证书。在这里我说继续这个网站)。但是当相同的URL被Java客户端(在我的情况下)击中时,我得到上述错误。为了把它放到信任库中,我尝试了以下三个选项:

选项1

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

选项2

在环境变量中设置如下

CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

选项3

在环境变量中设置如下

JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

结果

但是什么都不管用。

最后工作是执行Java方法建议如何处理无效的SSL证书与Apache HttpClient?通过Pascal Thivent,即执行程序InstallCert。

但这种方法适用于开发盒设置,但我不能在生产环境中使用它。

我想知道为什么上面提到的三种方法都不工作,而我已经通过设置在App2服务器的server.xml中提到了相同的值,在truststore中也提到了相同的值

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore")和System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

在App1程序中。

要了解更多信息,这是我如何建立联系:

URL url = new URL(urlStr);

URLConnection conn = url.openConnection();

if (conn instanceof HttpsURLConnection) {

  HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();
  
  conn1.setHostnameVerifier(new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
      return true;
    }
  });

  reply.load(conn1.getInputStream());

当前回答

遇到同样的问题时,我正在使用jdk1.8.0_171。我在这里尝试了前2个解决方案(使用keytool添加证书和另一个解决方案,其中有一个黑客),但他们不适合我。

我把JDK升级到1.8.0_181,它就像一个魅力。

其他回答

您需要将App2的证书添加到所使用的JVM的信任库文件中,该文件位于$JAVA_HOME\lib\security\cacerts。

首先,您可以通过运行以下命令检查您的证书是否已经在信任存储库中: keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts"(不需要提供密码)

如果您的证书丢失,您可以通过浏览器下载它,并使用以下命令将其添加到信任存储区:

keytool -import -noprompt -trustcacerts -alias <AliasName> -file   <certificate> -keystore <KeystoreFile> -storepass <Password>

例子:

keytool -import -noprompt -trustcacerts -alias myFancyAlias -file /path/to/my/cert/myCert.cer -keystore /path/to/my/jdk/jre/lib/security/cacerts/keystore.jks -storepass changeit

导入后,您可以再次运行第一个命令来检查是否添加了证书。

Sun/Oracle的信息可以在这里找到。

我们也有同样的问题,我们做了以下所有的事情。

重新导入服务器SSL证书。 确保weblogic使用正确的caecerts。

最后我们的weblogic启用weblogic调试模式,发现有“NOT HANDSHAKED”异常。

我们发现的原因是,客户端系统使用的是jdk 1.6,服务器使用的是更高的jdk版本(1.8),因为有一些TLS版本不匹配导致了这个问题。

Weblogic团队通过在服务器参数中添加以下行来调整服务器配置。

-Djdk.tls.client.protocol=TLSv1.2 -DUseSunHttpHandler=true.

对我来说,这篇文章中公认的解决方案并不奏效:https://stackoverflow.com/a/9619478/4507034。

相反,我设法通过将认证导入到我的机器信任的认证来解决这个问题。

步骤:

转到URL(例如。https://localhost:8443/yourpath),其中认证不起作用。 导出上述帖子中描述的认证。 在windows机器上打开:管理计算机证书 进入受信任的根证书颁发机构->证书 在这里导入您的your_certification_name。cer文件。

我也有这个问题。

通过将SSL证书添加到.keystore,我尝试了几乎所有方法,但是,它不能与Java1_6_x一起工作。 对我来说,如果我们开始使用新版本的Java, Java1_8_x作为JVM,这是有帮助的。

对于OkHttpClient,这个解决方案适合我。 它可能会帮助使用图书馆的人……

try {

            String proxyHost = "proxy_host";
            String proxyUsername = "proxy_username";
            String proxyPassword = "proxy_password";

            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, "port goes here"));

            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                    @Override
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                    @Override
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient client = new OkHttpClient().newBuilder()
                    .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
                    .hostnameVerifier((hostname, session) -> true)
                    .connectTimeout(timeout, TimeUnit.SECONDS)
                    .proxy(proxy)
                    .proxyAuthenticator((route, response) -> {
                        String credential = Credentials.basic(proxyUsername, proxyPassword);
                        return response.request().newBuilder()
                                .header("Proxy-Authorization", credential)
                                .build();
                    })
                    .build();

            MediaType mediaType = MediaType.parse("application/json");
            RequestBody requestBody = RequestBody.create(payload, mediaType);

            Request request = new Request.Builder()
                    .url(url)
                    .header("Authorization", "authorization data goes here")
                    .method(requestMethod, requestBody)
                    .build();

            Response response = client.newCall(request).execute();

            resBody = response.body().string();

            int responseCode = response.code();

        } catch (Exception ex) {
        }