Edit :- 试图以更加流畅的方式格式化问题并接受答案 Blog
这是原始问题: -
我收到了这个错误
详细消息sun.security.validator.ValidatorException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到所请求目标的有效证书路径导致javax.net.ssl.SSLHandshakeException:sun.security.validator . ValidatorException:PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到所请求目标的有效证书路径
我使用tomcat 6作为网络服务器 . 我有两个https webbapplication安装在不同的tomcat上的differte端口,但在同一台机器上 . 说 App1(port 8443)
和 App2(port 443)
. App1
连接到 App2
. 当 App1
连接到 App2 i
时出现以上错误 . 我知道这是非常常见的错误,所以在不同的论坛和网站上遇到了很多解决方案 . 我在tomcat的 server.xml
下面有条目,即
keystoreFile="c:/.keystore"
keystorePass="changeit"
每个站点都说同样的原因,即app2提供的证书不在app1 jvm的可信存储中 . 这似乎也是如此,当我厌倦了在IE浏览器中访问相同的URL,它的工作原理(温暖,这个网站的安全证书存在问题 . 这里我说继续这个网站)但是当相同的网址遭到打击时java客户端(在我的例子中) . 所以我得到了上述错误 . 所以把它放在trustore我尝试了这些树选项,即
Option1
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
Option2 在环境变量中设置如下
CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
Option3 在环境变量中设置如下
JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value
But nothing worked .
What at last worked 正在执行Pascal Thivent在How to handle invalid SSL certificates with Apache HttpClient?中建议的java方法,即执行程序InstallCert .
But this approach is fine for devbox setup but i can not use it at production environment.
我想知道为什么当我在 app2
服务器的 server.xml
中提到相同的值并且通过设置在truststore中的相同值时,上面提到的三种方法都不起作用
System.setProperty("javax.net.ssl.trustStore", "C:/.keystore") and System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
在 app1
计划中 .
有关更多信息,这是我如何 Build 连接
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());
14 回答
另一个原因可能是JDK的过时版本 . 我使用的是jdk版本1.8.0_60,只需更新到最新版本即可解决证书问题 .
下面的代码适用于我:
它是Java的一个缺陷,没有使用像MacOS X那样的标准操作系统密钥库 . 我今天提交了一个更改请求,请参阅http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8185892
对我来说,这个错误在尝试连接到处理SSL的NGINX反向代理后面的进程时也出现了 .
原来问题是证书没有连接整个证书链 . 当我添加中间证书时,问题就解决了 .
希望这可以帮助 .
您需要将 App2 的证书添加到位于
%JAVA_HOME%\lib\security\cacerts
的已使用JVM的信任库文件中 .首先,您可以通过运行以下命令来检查您的证书是否已在信任库中:
keytool -list -keystore "%JAVA_HOME%/jre/lib/security/cacerts"
(您无需提供密码)如果缺少证书,可以通过浏览器下载证书并使用以下命令将其添加到信任库:
keytool -import -noprompt -trustcacerts -alias <AliasName> -file <certificate> -keystore <KeystoreFile> -storepass <Password>
在导入之后,您可以再次运行第一个命令来检查您的证书是否已添加 .
可以找到Sun / Oracle信息here .
•当我收到错误时,我试图谷歌表达式的含义,我发现,当服务器更改其HTTPS SSL证书时,会出现此问题,而我们的旧版本的java无法识别根证书颁发机构(CA) .
•如果您可以在浏览器中访问HTTPS URL,则可以更新Java以识别根CA.
•在浏览器中,转到Java无法访问的HTTPS URL . 单击HTTPS证书链(Internet Explorer中有锁定图标),单击锁定以查看证书 .
•转到证书的“详细信息”和“复制到文件” . 以 Base64 (.cer) 格式复制它 . 它将保存在您的桌面上 .
•安装证书,忽略所有警报 .
•这是我收集我尝试访问的URL的证书信息的方式 .
现在我不得不让我的java版本知道证书,以便进一步拒绝识别URL . 在这方面,我必须提一下,我在谷歌的 \jre\lib\security 位置默认保留根证书信息,并且访问的默认密码是: changeit.
要查看cacerts信息,请遵循以下步骤:
•单击“开始”按钮 - >“运行”
•键入cmd . 命令提示符将打开(您可能需要以管理员身份打开它) .
•转到
Java/jreX/bin
目录•键入以下内容
它给出了包含在其中的当前证书的列表密钥库 . 它看起来像这样:
•现在我必须将以前安装的证书包含在cacerts中 .
•为此,以下是程序:
如果您使用的是Java 7:
•然后,它会将证书信息添加到cacert文件中 .
这是我在上面提到的Exception中找到的解决方案!!
在Linux下使用Tomcat 7,这就行了 .
在Linux下,
$JAVA_HOME
并不总是设置,但通常/etc/alternatives/jre
指向$JAVA_HOME/jre
如何在Tomcat 7中工作
我想在Tomcat应用程序中支持自签名证书,但是 the following snippet failed to work
这就解决了我的问题:
1)下载.crt文件
<your domain>
替换为您的域名(例如jossef.com
)2)在Java的cacerts证书库中应用.crt文件
将
<your domain>
替换为您的域名(例如jossef.com
)将
<JAVA HOME>
替换为您的java主目录3)哈哈
即使我在
Java
的默认证书商店中安装了我的证书, Tomcat ignores that (似乎是's not configured to use Java'的默认证书商店) .要解决此问题,请在代码中的某处添加以下内容:
对于在Ubuntu服务器上运行的Tomcat,要找出正在使用的Java,请使用“ps -ef | grep tomcat”命令:
样品:
然后,我们可以进入: cd /usr/local/java/jdk1.7.0_15/jre/lib/security
默认 cacerts 文件位于此处 . 将不受信任的证书插入其中 .
就我而言,问题是网络服务器只发送证书和中间CA,而不是根CA.添加此JVM选项解决了问题:
-Dcom.sun.security.enableAIAcaIssuers=true
Source
当我遇到同样的问题时,我正在使用
jdk1.8.0_171
. 我在这里尝试了前2个解决方案(使用keytool添加证书和另一个有黑客入侵的解决方案),但它们对我不起作用 .我将JDK升级到
1.8.0_181
,它就像一个魅力 .我也有这个问题 .
我通过向.keystore添加SSL证书来尝试几乎所有内容,但是,它无法使用Java1_6_x . 对我来说,如果我们开始使用较新版本的Java,Java1_8_x作为JVM,它会有所帮助 .
我的cacerts文件完全是空的 . 我通过从我的Windows机器(使用Oracle Java 7)复制cacerts文件并将其scp到我的Linux机箱(OpenJDK)来解决这个问题 .
然后在linux机器上
到目前为止,它运作得很好 .
我写了一个小的win32(WinXP 32位testet)愚蠢的cmd(命令行)脚本,它在程序文件中查找所有java版本并为它们添加一个证书 . 密码需要是默认的“changeit”或在脚本中自行更改:-)