解决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