解决javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIXpath构build失败错误?

编辑: –试图格式化的问题和接受的答案在我的博客更多的方式

这是原来的问题:

我得到这个错误

详细消息sun.security.validator.ValidatorException:PKIXpath构build失败:
sun.security.provider.certpath.SunCertPathBuilderException:无法find有效的证书path到请求的目标

导致javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIXpath构build失败:sun.security.provider.certpath.SunCertPathBuilderException:无法find有效的证书path到请求的目标

我正在使用tomcat 6作为networking服务器。 我有两个https webbapplication安装在differte端口上不同的tomcat,但在同一台机器上。 说App1(port 8443)App2(port 443)App1连接到App2 。当App1连接到App2 i以上错误。 我知道这是非常常见的错误,所以在不同的论坛和网站上遇到很多解决scheme。 我有两个tomcat即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"); 

Option2在环境variables中设置如下

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

Option3在环境variables中设置如下

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

但没有任何工作

最后的工作是执行如何处理无效的SSL证书与Apache HttpClientbuild议的java方法? 由帕斯卡尔Thivent即执行程序InstallCert。

但是这种方法对于devbox安装很好,但是我不能在生产环境中使用它。

我想知道为什么上面提到的三种方法不起作用,当我提到app2服务器的server.xml中相同的值和信任库中相同的值通过设置

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and 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()); 

您需要将App2的证书添加到位于%JAVA_HOME%\lib\security\cacerts的已用JVM的信任库文件。

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

如果您的证书丢失,您可以通过使用浏览器下载证书来获取证书,并使用以下命令将其添加到信任库中:

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

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

Sun / Oracle信息可以在这里find。

javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIXpath构build失败:sun.security.provider.certpath.SunCertPathBuilderException:无法find有效的证书path到所请求的目标

•当我收到错误信息时,我尝试Googleexpression式的含义,发现当服务器更改HTTPS SSL证书时会发生此问题,而旧版本的Java不能识别根证书颁发机构(CA) 。

•如果您可以在浏览器中访问HTTPS URL,则可以更新Java以识别根CA.

•在浏览器中,转至Java无法访问的HTTPS URL。 点击HTTPS证书链(Internet Explorer中有锁图标),点击锁查看证书。

•转到证书的“详细信息”和“复制到文件”。 以Base64(.cer)格式复制。 它将被保存在桌面上。

•安装证书,忽略所有警报。

这就是我收集我尝试访问的URL的证书信息的方式。

现在我必须让我的Java版本了解证书,以便进一步它不拒绝承认的URL。 在这方面,我必须提到,我已经在JDK的\ jre \ lib \ security位置默认保留了根证书信息,并且访问的默认密码是: changeit。

要查看cacerts信息,请遵循以下步骤:

•点击开始button – >运行

•键入cmd。 命令提示符打开(您可能需要以pipe理员身份打开它)。

转到Java/jreX/bin目录

•键入以下内容

keytool -list -keystore D:\ Java \ jdk1.5.0_12 \ jre \ lib \ security \ cacerts

它给出了密钥库中包含的当前证书的列表。 它看起来像这样:

C:\ Documents and Settings \ NeelanjanaG> keytool -list -keystore D:\ Java \ jdk1.5.0_12 \ jre \ lib \ security \ cacerts

input密钥库密码:changeit

密钥库types:jks

密钥库提供商:SUN

您的密钥库包含44个条目

verisignclass3g2ca,2004年3月26日,trustedCertEntry,

证书指纹(MD5):A2:33:9B:4C:74:78:73:D4:6C:E7:C1:F3:8D:CB:5C:E9

entrustclientca,2003年1月9日,trustedCertEntry,

证书指纹(MD5):0C:41:2F:13:5B:A0:54:F5:96:66:2D:7E:CD:0E:03:F4

thawtepersonalbasicca,1999年2月13日,trustedCertEntry,

证书指纹(MD5):E6:0B:D2:C9:CA:2D:88:DB:1A:71:0E:4B:78:EB:02:41

addtrustclass1ca,2006年5月1日,trustedCertEntry,

证书指纹(MD5):1E:42:95:02:33:92:6B:B9:5F:C0:7F:DA:D6:B2:4B:FC

verisignclass2g3ca,2004年3月26日,trustedCertEntry,

证书指纹(MD5):F8:BE:C4:63:22:C9:A8:46:74:8B:B8:1D:1E:4A:2B:F6

•现在我必须将之前安装的证书包含在cacerts中。

•为此,程序如下:

keytool -import -noprompt -trustcacerts -alias ALIASNAME -file FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass PASSWORD

如果您正在使用Java 7:

keytool -importcert -trustcacerts -alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit

•然后将证书信息添加到cacert文件中。

这是上面提到的例外的解决scheme!

如何在Tomcat 7中工作

我想在Tomcat应用程序中支持自签名证书,但以下代码段失败

 import java.io.DataOutputStream; import java.net.HttpURLConnection; import java.net.URL; public class HTTPSPlayground { public static void main(String[] args) throws Exception { URL url = new URL("https:// ... .com"); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); httpURLConnection.setDoOutput(true); DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream()); String serializedMessage = "{}"; wr.writeBytes(serializedMessage); wr.flush(); wr.close(); int responseCode = httpURLConnection.getResponseCode(); System.out.println(responseCode); } } 

这是什么解决了我的问题:

1)下载.crt文件

 echo -n | openssl s_client -connect <your domain>:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/<your domain>.crt 
  • <your domain>replace<your domain> (例如jossef.com

2)在Java的cacerts证书存储中应用.crt文件

 keytool -import -v -trustcacerts -alias <your domain> -file ~/<your domain>.crt -keystore <JAVA HOME>/jre/lib/security/cacerts -keypass changeit -storepass changeit 
  • <your domain>replace<your domain> (例如jossef.com
  • 用你的java主目录replace<JAVA HOME>

3)破解它

即使iv'e安装我的证书在Java的默authentication书存储, Tomcat忽略 (似乎它没有configuration为使用Java的默authentication书存储)。

要破解这个,在代码中添加下面的代码:

 String certificatesTrustStorePath = "<JAVA HOME>/jre/lib/security/cacerts"; System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath); // ... 

我的cacerts文件完全是空的。 我通过从我的Windows机器(使用Oracle Java 7)复制cacerts文件解决了这个问题,并将其分发到我的Linux机器上(OpenJDK)。

 cd %JAVA_HOME%/jre/lib/security/ scp cacerts mylinuxmachin:/tmp 

然后在linux机器上

 cp /tmp/cacerts /etc/ssl/certs/java/cacerts 

到目前为止效果很好。

对于在Ubuntu服务器上运行的Tomcat,要找出正在使用哪个Java,请使用“ps -ef | grep tomcat”命令:

样品:

 /home/mcp01$ **ps -ef |grep tomcat** tomcat7 28477 1 0 10:59 ? 00:00:18 **/usr/local/java/jdk1.7.0_15/bin/java** -Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties -Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat7/endorsed -classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start 1005 28567 28131 0 11:34 pts/1 00:00:00 grep --color=auto tomcat 

然后,我们可以进入: cd /usr/local/java/jdk1.7.0_15/jre/lib/security

默认的cacerts文件位于这里。 插入不可信证书。

在Linux下使用Tomcat 7,这个技巧。

  String certificatesTrustStorePath = "/etc/alternatives/jre/lib/security/cacerts"; System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath); System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 

在Linux下,$ JAVA_HOME并不总是安装,但通常是/ etc / alternatives / jre指向$ JAVA_HOME / jre

我写了一个小型的Win32(WinXP 32bit testet)愚蠢的cmd(commandline)脚本,它在程序文件中查找所有java版本,并向它们添加一个证书。 密码需要是默认的“changeit”或者在脚本中自己修改:-)

 @echo off for /F %%d in ('dir /B %ProgramFiles%\java') do ( %ProgramFiles%\Java\%%d\bin\keytool.exe -import -noprompt -trustcacerts -file some-exported-cert-saved-as.crt -keystore %ProgramFiles%\Java\%%d\lib\security\cacerts -storepass changeit ) pause 

我也有这个问题。

我通过将SSL证书添加到.keystore来尝试几乎所有的东西,但是它并不适用于Java1_6_x。 对我来说,如果我们开始使用Java的新版本Java1_8_x作为JVM,那么这对我们有所帮助。

对我来说,在尝试连接到处理SSL的NGINX反向代理后面的进程时,也出现了这个错误。

事实certificate,问题是没有整个证书链串联的证书。 当我添加中级证书时,问题就解决了。

希望这可以帮助。

它的一个Java的缺陷没有使用标准的操作系统密钥库,像MacOS X.我今天提出了一个变更请求见http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8185892