I am trying to connect to a server with a Java Http client to make a web service call. If I turn net debugging on with the below code..
System.setProperty("javax.net.debug", "all");
I am seeing that certificates from Entrust seem to be added as trusted certificates. Among those added were the below...
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
It seems as if the server is using a cert from Entrust because I also see in the debug...
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
And yet during the handshake process I get the below exception...
***
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
答案 0 :(得分: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];
}
}
TrustManager[] trustArray = [new TrustAll()] as TrustManager[]
SSLContext ctx = SSLContext.getInstance("TLSv1");
ctx.init(null, trustArray, null);
// create an http client builder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setSslcontext(ctx)
httpclient = httpClientBuilder.build();
答案 1 :(得分: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_HOME位置。