报错sun.security.validator.ValidatorException: PKIX path building failed

在执行webservice的过程中,出现如下异常:

 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

这是缺少安全证书时出现的异常,解决方案就是将你要访问的webservice的安全认证证书导入到客户端即可。

以下是获取安全证书的一种方法:

用如下程序获取证书:

在eclipse中执行InstallCert.java文件:

/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
import java.io.*;
 
import java.security.*;
import java.security.cert.*;
 
import javax.net.ssl.*;
 
public class InstallCert {
 
    public static void main(String[] args) throws Exception {
	String host;
	int port;
	char[] passphrase;
	String[] h={"litc.xforceplus.com"};//这是要访问的webservice的网址
	if ((h.length == 1) || (h.length == 2)) {
	    String[] c = h[0].split(":");
	    host = c[0];
	    port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
	    String p = (h.length == 1) ? "changeit" : h[1];
	    passphrase = p.toCharArray();
	} else {
	    System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
	    return;
	}
 
	File file = new File("jssecacerts");
	if (file.isFile() == false) {
	    char SEP = File.separatorChar;
	    File dir = new File(System.getProperty("java.home") + SEP
		    + "lib" + SEP + "security");
	    file = new File(dir, "jssecacerts");
	    if (file.isFile() == false) {
		file = new File(dir, "cacerts");
	    }
	}
	System.out.println("Loading KeyStore " + file + "...");
	InputStream in = new FileInputStream(file);
	KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
	ks.load(in, passphrase);
	in.close();
 
	SSLContext context = SSLContext.getInstance("TLS");
	TrustManagerFactory tmf =
	    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
	tmf.init(ks);
	X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
	SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
	context.init(null, new TrustManager[] {tm}, null);
	SSLSocketFactory factory = context.getSocketFactory();
 
	System.out.println("Opening connection to " + host + ":" + port + "...");
	SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
	socket.setSoTimeout(10000);
	try {
	    System.out.println("Starting SSL handshake...");
	    socket.startHandshake();
	    socket.close();
	    System.out.println();
	    System.out.println("No errors, certificate is already trusted");
	} catch (SSLException e) {
	    System.out.println();
	    e.printStackTrace(System.out);
	}
 
	X509Certificate[] chain = tm.chain;
	if (chain == null) {
	    System.out.println("Could not obtain server certificate chain");
	    return;
	}
 
	BufferedReader reader =
		new BufferedReader(new InputStreamReader(System.in));
 
	System.out.println();
	System.out.println("Server sent " + chain.length + " certificate(s):");
	System.out.println();
	MessageDigest sha1 = MessageDigest.getInstance("SHA1");
	MessageDigest md5 = MessageDigest.getInstance("MD5");
	for (int i = 0; i < chain.length; i++) {
	    X509Certificate cert = chain[i];
	    System.out.println
	    	(" " + (i + 1) + " Subject " + cert.getSubjectDN());
	    System.out.println("   Issuer  " + cert.getIssuerDN());
	    sha1.update(cert.getEncoded());
	    System.out.println("   sha1    " + toHexString(sha1.digest()));
	    md5.update(cert.getEncoded());
	    System.out.println("   md5     " + toHexString(md5.digest()));
	    System.out.println();
	}
 
	System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
	String line = reader.readLine().trim();
	int k;
	try {
	    k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
	} catch (NumberFormatException e) {
	    System.out.println("KeyStore not changed");
	    return;
	}
 
	X509Certificate cert = chain[k];
	String alias = host + "-" + (k + 1);
	ks.setCertificateEntry(alias, cert);
 
	OutputStream out = new FileOutputStream("jssecacerts");
	ks.store(out, passphrase);
	out.close();
 
	System.out.println();
	System.out.println(cert);
	System.out.println();
	System.out.println
		("Added certificate to keystore 'jssecacerts' using alias '"
		+ alias + "'");
    }
 
    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
 
    private static String toHexString(byte[] bytes) {
	StringBuilder sb = new StringBuilder(bytes.length * 3);
	for (int b : bytes) {
	    b &= 0xff;
	    sb.append(HEXDIGITS[b >> 4]);
	    sb.append(HEXDIGITS[b & 15]);
	    sb.append(' ');
	}
	return sb.toString();
    }
 
    private static class SavingTrustManager implements X509TrustManager {
 
	private final X509TrustManager tm;
	private X509Certificate[] chain;
 
	SavingTrustManager(X509TrustManager tm) {
	    this.tm = tm;
	}
 
	public X509Certificate[] getAcceptedIssuers() {
	    throw new UnsupportedOperationException();
	}
 
	public void checkClientTrusted(X509Certificate[] chain, String authType)
		throws CertificateException {
	    throw new UnsupportedOperationException();
	}
 
	public void checkServerTrusted(X509Certificate[] chain, String authType)
		throws CertificateException {
	    this.chain = chain;
	    tm.checkServerTrusted(chain, authType);
	}
    }
 
}

run -->Java application,控制台输出:

Loading KeyStore C:\Program Files\Java\jre1.8.0_152\lib\security\cacerts...
Opening connection to litc.xforceplus.com:443...
Starting SSL handshake...
 
javax.net.ssl.SSLException: java.lang.UnsupportedOperationException
	at sun.security.ssl.Alerts.getSSLException(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at InstallCert.main(InstallCert.java:87)
Caused by: java.lang.UnsupportedOperationException
	at InstallCert$SavingTrustManager.getAcceptedIssuers(InstallCert.java:171)
	at sun.security.ssl.AbstractTrustManagerWrapper.checkAlgorithmConstraints(Unknown Source)
	at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(Unknown Source)
	at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unknown Source)
	at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
	at sun.security.ssl.Handshaker.processLoop(Unknown Source)
	at sun.security.ssl.Handshaker.process_record(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	... 3 more
 
Server sent 3 certificate(s):
 
 1 Subject CN=*.xforceplus.com, ST=上海市, L=上海市, O=上海云砺信息科技有限公司, C=CN
   Issuer  CN=WoSign OV SSL CA, O=WoSign CA Limited, C=CN
   sha1    bb 10 54 02 19 1c fa 9b ac 08 ff 08 b4 a4 89 01 fb dd cf ed 
   md5     23 5b ad 02 60 48 12 c8 a4 63 eb 8d 8d 7e 1b be 
 
 2 Subject CN=WoSign OV SSL CA, O=WoSign CA Limited, C=CN
   Issuer  CN=Certum Trusted Network CA, OU=Certum Certification Authority, O=Unizeto Technologies S.A., C=PL
   sha1    fa ee 1f 69 0e dd 55 37 3c 35 e4 91 ef 05 14 f3 ee 94 45 a5 
   md5     f1 db b5 f7 4c fe 54 46 c8 a2 73 dc 3e 8a 45 ad 
 
 3 Subject CN=Certum Trusted Network CA, OU=Certum Certification Authority, O=Unizeto Technologies S.A., C=PL
   Issuer  CN=Certum CA, O=Unizeto Sp. z o.o., C=PL
   sha1    92 9b ad f2 60 81 52 34 90 ed c9 11 54 b3 80 a4 77 6e 21 85 
   md5     6b 83 99 12 74 59 6d 9e fe 48 82 5e 73 b7 04 40 
 
Enter certificate to add to trusted keystore or 'q' to quit: [1]

输入1,然后直接回车,会在InstallCert.java所在项目的根目录下生成一个名为‘jssecacerts’的证书。

如果是服务器上,可以将‘jssecacerts’的证书放到一个目录下/erp/test/apps/apps_st/comn/java/classes/com/zshare/,

在调用webservice接口前去加载这个证书:
 

System.setProperty("javax.net.ssl.trustStore", "/erp/test/apps/apps_st/comn/java/classes/com/zshare/jssecacerts"); 

网上看到的其他方法:

将证书copy到$JAVA_HOME/jre/lib/security目录下,或者通过以下方式

System.setProperty("javax.net.ssl.trustStore", "D:\\UTA\\DOC_E_Health_XML\\Keystore\\jssecacerts");

注意:要重新启动你的应用服务器,因是静态加载,证书才能被运用上。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章