PKIXpathbuild立失败:无法find有效的证书path到请求的目标
我打电话给一些HTTPS的networking服务,下面的客户端:
import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.net.HttpURLConnection; import java.net.URL; import javax.net.ssl.HttpsURLConnection; /** * Handles http and https connections. It sends XML request over http (or https) * to SOAP web service and receive the XML reply. * * @author mhewedy * @date 30.10.2010 */ public class HttpWSXmlClient { private final String ws_url; private byte[] requestData; public HttpWSXmlClient(String wsUrl) { this.ws_url = wsUrl; } public void readRequest(String xmlRequestFilePath) { try { InputStream istream = new FileInputStream(xmlRequestFilePath); byte[] data = stream2Bytes(istream); istream.close(); this.requestData = data; } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } /** * * @param ps * PrintStream object to send the debugging info to. * @return * @throws IOException */ public byte[] sendAndRecieve(PrintStream ps) throws IOException { if (requestData == null) throw new RuntimeException( "the request data didn't initialized yet."); if (ps != null) ps.println("Request:\n" + new String(requestData)); URL url = new URL(ws_url); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); // or HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setRequestProperty("content-type", "text/xml"); connection.connect(); OutputStream os = connection.getOutputStream(); os.write(requestData); InputStream is = connection.getInputStream(); byte[] rply = stream2Bytes(is); if (ps != null) ps.println("Response:\n" + new String(rply)); os.close(); is.close(); connection.disconnect(); return rply; } public byte[] sendAndRecieve() throws IOException { return sendAndRecieve(null); } private byte[] stream2Bytes(InputStream istream) throws IOException { ByteArrayOutputStream outstream = new ByteArrayOutputStream(); int c; while ((c = istream.read()) != -1) { if (c != 0x0A && c != 0x0D) // prevent new line character from being // written { if (c == 0x09) c = 0x20; // prevent tab character from being written, // instead write single space char outstream.write(c); } } byte[] ret = outstream.toByteArray(); outstream.close(); return ret; } }
testing:
public class Test { private static final String WS_URL = "https://some_server/path/to/ws"; public static void main(String[] args) throws Exception { HttpWSXmlClient client = new HttpWSXmlClient(WS_URL); client.readRequest("request.xml"); client.sendAndRecieve(System.out); } }
我得到了以下输出:
Exception in thread "Main Thread" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1591) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:415) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166) at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133) at com.se.swstest.HttpWSXmlClient.sendAndRecieve(HttpWSXmlClient.java:63) at com.se.swstest.Test.main(Test.java:11) Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:285) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:191) at sun.security.validator.Validator.validate(Validator.java:218) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014) ... 12 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:280) ... 18 more
我需要将任何证书放在jdk / jre / lib / security? 另外,我有一个xxx_IE.crt和xxx_FX.crt(分别适用于Firefox和IE,并且不适用于上述Java客户端,那么是否需要为Java客户端指定特定的证书?
谢谢。
你需要设置证书打这个url。 使用下面的代码来设置密钥库:
System.setProperty("javax.net.ssl.trustStore","clientTrustStore.key"); System.setProperty("javax.net.ssl.trustStorePassword","qwerty");
我遇到过这几次,这是由于证书链不完整。 如果使用的是标准Java信任库,则可能没有完成validation所连接的SSL站点的证书所需的证书链所需的证书。
我遇到了一些DigiCert证书的问题,必须自己手动添加中间证书。
Java 8解决scheme:我刚刚遇到了这个问题,并通过将远程站点的证书添加到我的Java密钥库来解决此问题。 我的解决scheme基于myshittycode博客上的解决scheme,该博客基于mykong博客中的以前的解决scheme 。 这些博客文章解决scheme归结为下载一个名为InstallCert的程序,它是一个可以从命令行运行的Java类来获取证书。 然后,继续在Java的密钥库中安装证书。
InstallCert自述文件适合我。 您只需要运行以下命令:
-
javac InstallCert.java
-
java InstallCert [host]:[port]
(运行命令时,input要添加到列表中的证书的给定列表编号 – 可能只是1 ) -
keytool -exportcert -alias [host]-1 -keystore jssecacerts -storepass changeit -file [host].cer
-
sudo keytool -importcert -alias [host] -keystore [path to system keystore] -storepass changeit -file [host].cer
如果需要的话,请参阅引用的README文件。
以下是我用于将站点的公用证书安装到系统密钥库中以供使用的解决scheme。
使用以下命令下载证书:
unix,linux,mac
openssl s_client -connect [host]:[port|443] < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > [host].crt
视窗
openssl s_client -connect [host]:[port|443] < NUL | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > [host].crt
这将创build一个可用于导入到密钥库的crt。
使用以下命令安装新证书:
keytool -import -alias "[host]" -keystore [path to keystore] -file [host].crt
这将允许您从导致exception的站点导入新的证书。
当我尝试从Java代码发起SOAP请求时,我遇到了这个问题。 对我有效的是:
-
通过浏览器中的URL获取服务器证书: http : //docs.bvstools.com/home/ssl-documentation/exporting-certificate-authorities-cas-from-a-website此链接有获取服务器的所有步骤证书
-
一旦你有了服务器证书,你可以按照http://java.globinch.com/enterprise-java/security/pkix-path-building-failed-validation-sun-security-validatorexception/#Valid-Certification-Path-to-请求目标; 。
复制链接中的文本,以防链接死亡:
您只需要将服务器证书添加到受信任的Java密钥存储区,即可解决此错误。 首先,您需要从服务器下载文档。
一旦你的硬盘上有证书,你可以将其导入到Java信任存储。 要将证书导入到受信任的Java密钥库中,可以使用java的“keytool”工具。 在命令提示符下,导航到JRE bin文件夹,在我的情况下,path是:C:\ Program Files \ Java \ jdk1.7.0_75 \ jre \ bin。 然后使用keytool命令如下将证书导入到JRE。
keytool -import -alias _alias_name_ -keystore .. \ lib \ security \ cacerts -file _path_to_cer_file
它会要求input密码。 默认情况下,密码是“changeit”。 如果密码不同,您可能无法导入证书。
在Mac OS上,我必须使用系统钥匙串访问工具打开服务器的自签名证书,导入它,dobubleclick它,然后select“始终信任”(即使我在导入器中设置相同)。 在那之前,我当然用java运行java key来把-importcert把同样的文件导入cacert存储。
对于我来说,在调用web服务调用时遇到了这个错误,请确保该网站有一个有效的ssl,即url侧面的logo被选中,否则需要将证书添加到你的机器中的可信密钥存储
我也面临这种types的问题。我正在使用tomcat服务器,然后我把赞同的文件夹在tomcat然后开始working.And也取代了JDK1.6 1.7然后也工作。最后我学习SSL然后我解决了这种types的问题首先你需要从服务提供商服务器下载证书,然后你握手成功。 1.试着在你的服务器上放置背书文件夹2.使用jdk1.7
Next 3.尝试使用SSL下载有效的证书