Java 为什么我会得到;在证书路径中找不到证书的颁发者证书;已知和受信任证书的错误?
我正在尝试使用JavaHTTP客户端连接到服务器以进行web服务调用。如果我用下面的代码打开网络调试Java 为什么我会得到;在证书路径中找不到证书的颁发者证书;已知和受信任证书的错误?,java,ssl,https,Java,Ssl,Https,我正在尝试使用JavaHTTP客户端连接到服务器以进行web服务调用。如果我用下面的代码打开网络调试 System.setProperty("javax.net.debug", "all"); 我看到来自委托的证书似乎被添加为受信任的证书。添加的内容包括以下内容 adding as trusted cert: Subject: CN=Entrust.net Certification Authority (2048), OU=(c) 1999 Entrust.net Limite
System.setProperty("javax.net.debug", "all");
我看到来自委托的证书似乎被添加为受信任的证书。添加的内容包括以下内容
adding as trusted cert:
Subject: CN=Entrust.net Certification Authority (2048), OU=(c) 1999 Entrust.net Limited, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), O=Entrust.net
Issuer: CN=Entrust.net Certification Authority (2048), OU=(c) 1999 Entrust.net Limited, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), O=Entrust.net
Algorithm: RSA; Serial number: 0x3863def8
Valid from Fri Dec 24 12:50:51 EST 1999 until Tue Jul 24 10:15:12 EDT 2029
似乎服务器正在使用来自委托的证书,因为我在调试中也看到了
main, READ: TLSv1 Handshake, length = 2649
*** Certificate chain
chain [0] = [0] Version: 3
SerialNumber: 1356119177
IssuerDN: C=US,O=Entrust\, Inc.,OU=See www.entrust.net/legal-terms,OU=(c) 2012 Entrust\, Inc. - for authorized use only,CN=Entrust Certification Authority - L1K
Start Date: Wed Jul 15 11:50:20 EDT 2015
Final Date: Sun Jul 15 18:27:04 EDT 2018
但在握手过程中,我得到了以下例外
***
Caught: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed: java.security.cert.CertPathBuilderException:
No issuer certificate for certificate in certification path found.
main, SEND TLSv1 ALERT: fatal, description = certificate_unknown
我通过创建一个接受服务器证书的信任管理器来解决这个问题,并指示我的Apache HttpClient使用该信任管理器
private class TrustAll implements X509TrustManager
{
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}
我通过创建一个接受服务器证书的信任管理器来解决这个问题,并指示我的Apache HttpClient使用该信任管理器
private class TrustAll implements X509TrustManager
{
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException
{
}
public X509Certificate[] getAcceptedIssuers()
{
return new X509Certificate[0];
}
}
我可以通过向java客户机(jre的cacerts和jssecacerts)添加服务器证书来解决这个问题 如果我们以这种方式向java客户机添加证书,我们将要求jre信任此服务器的证书
echo | openssl s_client -showcerts -connect www.xyz.com:443 2>&1 |
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/cert.pem
#cacerts
keytool -import -alias certname -file /tmp/cert.pem -keystore
/usr/java/jdk1.8.0_45/jre/lib/security/cacerts -storepass changeit
#jssecacerts(Normally we remove this file)
keytool -import -alias certname -file /tmp/cert.pem -keystore
/usr/java/jdk1.8.0_45/jre/lib/security/jssecacerts -storepass changeit
如果这段客户端代码是通过应用服务器执行的,请重新启动应用服务器
确保您在环境变量中有openssl和keytool,并更改各自的JAVA主位置。我可以通过向JAVA客户端(jre的cacerts和jssecacerts)添加服务器证书来解决这个问题 如果我们以这种方式向java客户机添加证书,我们将要求jre信任此服务器的证书
echo | openssl s_client -showcerts -connect www.xyz.com:443 2>&1 |
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/cert.pem
#cacerts
keytool -import -alias certname -file /tmp/cert.pem -keystore
/usr/java/jdk1.8.0_45/jre/lib/security/cacerts -storepass changeit
#jssecacerts(Normally we remove this file)
keytool -import -alias certname -file /tmp/cert.pem -keystore
/usr/java/jdk1.8.0_45/jre/lib/security/jssecacerts -storepass changeit
如果这段客户端代码是通过应用服务器执行的,请重新启动应用服务器
确保您在环境变量中有openssl、keytool,并更改您各自的JAVA_主位置。IssuerDN与您显示的受信任证书不同,因此它可能是一个中间证书,而您的信任存储中没有中间证书。一个好的服务器应该包含中间证书,所以如果您控制了服务器,请修复它。否则,请查找中间证书并将其添加到您的信任存储中。根据这一点,如果我的信任存储中有根证书而不必添加中间证书,则应该足够了。您是否阅读了该链接中的?让我重复一下我已经说过的话:服务器应该在握手中包含中间证书,在这种情况下,只有根证书需要在您的信任存储中。糟糕的服务器不需要,所以您的信任存储也需要有这些中间证书才能正常工作。如果您对服务器有任何发言权,请使其成为一个性能良好的服务器。否则,请将中间证书添加到您的信任存储中,以便您可以与行为不端的服务器进行交互。因此,您是说服务器可能不包含中间证书,因此在这种情况下,我需要请求拥有该服务器的人向我发送一个中间证书以添加到我的信任存储中?我想我不清楚服务器端或我方(客户的信任存储)是否缺少证书?为了验证实际的服务器证书,必须使用整个证书链,并且必须信任根证书。如果中间证书丢失,则无法验证服务器证书。正如我所说,一个好的服务器将在SSL握手中包含中间证书。配置不好的服务器将无法解决此问题,但您可以通过在自己的信任存储中安装中间证书来解决此问题。这是一个针对配置不正确的服务器的解决方案,因此最好正确配置服务器,但该解决方案可以工作,因此,如果无法修复服务器,请使用它。
IssuerDN
与您显示的受信任证书不同,因此它可能是一个中间证书,而您的信任存储中没有中间证书。一个好的服务器应该包含中间证书,所以如果您控制了服务器,请修复它。否则,请查找中间证书并将其添加到您的信任存储中。根据这一点,如果我的信任存储中有根证书而不必添加中间证书,则应该足够了。您是否阅读了该链接中的?让我重复一下我已经说过的话:服务器应该在握手中包含中间证书,在这种情况下,只有根证书需要在您的信任存储中。糟糕的服务器不需要,所以您的信任存储也需要有这些中间证书才能正常工作。如果您对服务器有任何发言权,请使其成为一个性能良好的服务器。否则,请将中间证书添加到您的信任存储中,以便您可以与行为不端的服务器进行交互。因此,您是说服务器可能不包含中间证书,因此在这种情况下,我需要请求拥有该服务器的人向我发送一个中间证书以添加到我的信任存储中?我想我不清楚服务器端或我方(客户的信任存储)是否缺少证书?为了验证实际的服务器证书,必须使用整个证书链,并且必须信任根证书。如果中间证书丢失,则无法验证服务器证书。正如我所说,一个好的服务器将在SSL握手中包含中间证书。配置不好的服务器将无法解决此问题,但您可以通过在自己的信任存储中安装中间证书来解决此问题。这是一种针对配置不当的服务器的解决方案,因此最好正确配置服务器,但该解决方案有效,因此,如果无法修复服务器,请使用它。该信任管理器接受任何证书。这是根本不安全的。不要使用。该信任管理器接受任何证书。这是根本不安全的。不要使用。