`

解决PKIX:unable to find valid certification path to requested target 的问题

 
阅读更多

这两天在外网调用webservice的时候报这个异常

e: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 

经过检查确认,完整的异常信息应该如下:

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

在内网调用的时候是没有问题的,后来仔细检查发现啦一个问题,外网是使用的是HTTS,内网使用的是HTTP,而HTTS是加密协议需要数字证书才能访问

 

所以问题的根本是:

缺少安全证书时出现的异常。

解决问题方法:

将你要访问的webservice/url....的安全认证证书导入到客户端即可。

 

以下是获取安全证书的一种方法,通过以下程序获取安全证书:

 

package com.fangxin;

/*
 * 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.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class InstallCert {


	public static void main(String[] args) throws Exception {
		
		/**
		 * 例如调用的webservice的地址是 <br/>
		 * https://5454.43.33.120:3333/wssw-webservice/services/FpzxService <br/>
		 * 则:host:5454.43.33.120 <br/>
		 *     port:3333 <br/>
		 */
		//调用的webservice URL的主机名
		String host;
		//调用的webservice URL的端口号
		int port;
		char[] passphrase;
		if ((args.length == 1) || (args.length == 2)) {
			String[] c = args[0].split(":");
			host = c[0];
			port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
			String p = (args.length == 1) ? "changeit" : args[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);
		}
	}

}

  

 

编译InstallCert.java,然后执行:java InstallCert hostname(可以直接使用域名,例如:https://fp.gdltax.gov.cn/fpzx/,则域名是:fp.gdltax.gov.cn),比如:

java InstallCert www.twitter.com
会看到如下信息:

 

Loading KeyStore jssecacerts...
Opening connection to 61.140.99.120:8136...
Starting SSL handshake...

No errors, certificate is already trusted

Server sent 2 certificate(s):

 1 Subject EMAILADDRESS=liw@cndatacom.com, CN=www.gdltax.gov.cn, OU=CDC, O=China DataCom Corporation Limited, ST=guangdong, C=CN
   Issuer  EMAILADDRESS=liw@cndatacom.com, CN=www.gdltax.gov.cn, OU=CDC, O=China DataCom Corporation Limited, L=guangzhou, ST=guangdong, C=CN
   sha1    36 51 47 59 11 3d 7d 0e 53 4c fd 0c bc 50 d5 29 e4 43 e3 51 
   md5     9c 41 5e 69 4f 11 3a 8a 2c 98 dd 4b 3a 6d a4 1d 

 2 Subject EMAILADDRESS=liw@cndatacom.com, CN=www.gdltax.gov.cn, OU=CDC, O=China DataCom Corporation Limited, L=guangzhou, ST=guangdong, C=CN
   Issuer  EMAILADDRESS=liw@cndatacom.com, CN=www.gdltax.gov.cn, OU=CDC, O=China DataCom Corporation Limited, L=guangzhou, ST=guangdong, C=CN
   sha1    a1 b7 45 b7 b9 bb 3d 8e 02 24 04 9c 43 80 52 47 88 85 9d 9f 
   md5     16 91 e7 3a cb cb d9 27 2f 10 ef 0d d8 2c 1f 0f 

Enter certificate to add to trusted keystore or 'q' to quit: [1]

 

输入1,回车,然后会在当前的目录下产生一个名为“ssecacerts”的证书。

 

将证书拷贝到$JAVA_HOME/jre/lib/security目录下,或者通过以下方式:
System.setProperty("javax.net.ssl.trustStore", "你的jssecacerts证书路径");//注意这里的证书路径需要使用绝对路径

 


注意:因为是静态加载,所以要重新启动你的Web Server,证书才能生效。

 

分享到:
评论

相关推荐

    验证证书unable to find valid certification path to requested target

    分析: 当在Java中使用URL.openConnection().connect()方法进行HTTPS请求时,如果遇到PKIX path building failed... 参考资源中《验证证书unable to find valid certification path to requested target问题解决.txt》

    PKIX path building failed

    sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    InstallCert.java工具及使用方法.zip

    sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    gradle-trust-all:一个用于禁用 SSL 证书验证的 gradle 插件

    unable to find valid certification path to requested target 处理这种情况的常用 Java 方法是下载站点证书,将其导入密钥库并通过-Djavax.net.ssl.trustStore=... JVM 选项使用该密钥库。 有时

    解决PKIX path building failed的问题

    标题中的“解决PKIX path building failed的问题”是一个关于网络安全和证书验证的常见错误,通常出现在Java应用程序中。当一个程序尝试通过HTTPS连接到一个服务器时,如果Java的信任存储(Truststore)不包含服务器...

    PKIX path building failed解决java获取https的时遇到的证书问题

    unable to find valid certification path to requested target ``` 这个错误表明Java在尝试建立SSL/TLS连接时无法验证服务器提供的证书。这通常是由于缺少正确的中间证书或根证书,或者这些证书没有正确安装在Java...

    如何在JAVA中导入Wosign证书1

    具体表现为:“PKIX:unable to find valid certification path to requested target”。这是因为Java应用程序在进行HTTPS请求时,会依赖JDK自带的信任根证书来验证服务端证书的有效性。如果服务端所使用的根证书...

    InstallCert.zip

    "InstallCert.zip"这个文件和其描述"mvn PKIX path building failed: 进行中央库授权, unable to find valid certification path to requested target"揭示了一个常见的问题:在使用Maven进行构建时,由于缺少信任...

    java导入wosign证书修改意见1

    当Java程序尝试通过HTTPS连接到使用Wosign根证书签名的服务时,如Azure的REST API,可能会收到错误信息“PKIX:unable to find valid certification path to requested target”。这是因为Java的标准JRE库(JDK)的...

    关于IDEA2020.1新建项目maven PKIX 报错问题解决方法

    这个错误的主要原因是ValidatorException:PKIX path building failed : sun.security.provider.certpath.SunCertPathBuilderException : unable to find valid certification path to requested target。...

    SSL.7z,解决PKIX path building failed 的问题

    PKIX path building failed 的问题。解决本地环境中报错 PKIX path building failed 的问题。 其中有产生证书的代码,将运行产生的证书放在文档中指定位置即可

    解决PKIX path building failed的问题的AbstractCasProtocolUrlBasedTicketValidator类

    CAS默认走https,需要安装证书,但是自定义的证书貌似得不到信任,报PKIX path building failed。则可以修改源码来屏蔽错误。

    kerby-pkix-1.0.1-API文档-中文版.zip

    Maven坐标:org.apache.kerby:kerby-pkix:1.0.1; 标签:apache、kerby、pkix、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的...

    kerby-pkix-1.0.1-API文档-中英对照版.zip

    Maven坐标:org.apache.kerby:kerby-pkix:1.0.1; 标签:apache、kerby、pkix、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档...

    PKIX_maven_archetype.rar

    标题“PKIX_maven_archetype.rar”涉及到的是在使用Maven Archetype插件创建Maven项目时遇到的问题,以及与Java安全证书相关的错误。描述中提到的问题有两个主要方面:一是Maven Archetype创建的工程不完整,缺少了`...

    sslpoke:用于测试Java中TLS连接建立的工具

    SSLPoke 使用Java测试与主机的TLS连接的建立。...用法: 阳性测试:java -jar... System: Oracle Corporationpolicy.allowSystemProperty: Security: truejava.security.policy:CertPathValidator.PKIX:cert.provider.x509

    https解决SSLHandshakeException问题.zip

    虽然上述方法可以解决问题,但在实际应用中,应优先考虑提高安全性,例如更新设备的SSL/TLS库、使用受信任的证书和现代加密套件。在测试和调试过程中,务必遵循最小权限原则,只在必要时放宽安全设置。

    Trusted Path Debugger:用于 PKIX 路径构建的 Java 调试器失败错误-开源

    在 Java 中,在进行 HTTPS 连接时,人们通常会遇到以下异常堆栈跟踪: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider....

    密码学相关格式编码器解码器:DER、PEM、PKCS、PKIX.zip

    这些格式在实际应用中常常相互配合,例如,一个PEM格式的证书可能包含了用DER编码的证书内容,而这个证书又遵循了PKIX标准。了解并正确使用这些格式对于开发和维护安全的网络服务至关重要,比如HTTPS服务器的配置、...

    dane-pkix-cd:DANE用于证书发现

    DANE的主要目标是解决传统的TLS证书体系中的几个关键问题,如中间人攻击、证书滥用以及依赖于可信赖的证书颁发机构(CA)。通过将公钥信息直接存储在DNS记录中,DANE允许客户端通过DNS查询验证服务器的身份,而不是...

Global site tag (gtag.js) - Google Analytics