解决PKIX path building failed的问题

方法一:使用keytool手动导入证书,为JRE环境导入信任证书

摘自:http://www.cnblogs.com/wanghaixing/p/5630070.html

方法二:使用代码下载证书保存

摘自:https://blog.csdn.net/frankcheng5143/article/details/52164939

方法三:服务器不信任我们自己创建的证书,所以在代码中忽略证书信任问题。

摘自:http://mengyang.iteye.com/blog/575671


最后注意:检查eclipse/myeclipse的JDK或JRE,是否为你导入证书的JRE。

注意:myeclipse是自带JDK的,JDK中自带JRE,而我们通过命令导入的jre是系统环境变量下path的jre。

两者很可能不是同一个,要改myeclipse的配置。(具体操作很简单,windows-->preferences-->搜索jre)


推荐:

https://blog.csdn.net/ybygjy/article/details/12147281

http://www.cnblogs.com/wanghaixing/p/5630070.html#3866132


功能:把目标host证书保存到jre/lib/security/jssecacerts文件,亲测有效

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.*;
import javax.net.ssl.*;
import java.security.cert.*;
import org.junit.Test;

public class certUtils {
	private int port = 443;
	private char[] passphrase="changeit".toCharArray();

	/**
	 * @param host 例:www.80s.tw
	 * @param port	https默认为443端口
	 * @param passphrase keyStore密码
	 */
	public void installCert(String host, int port, char[] passphrase) {
		//文件分隔符
		char SEP = File.separatorChar;
		//获取jre/lib/security目录
		File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP
				+ "security");
		//新建文件jre/lib/security/jssecacerts,向文件输出时文件才真正创建
		File file = new File(dir, "jssecacerts");
		//jssecacerts文件不存在时,获取jre/lib/security/cacerts文件索引
		if (file.isFile() == false) {
			file = new File(dir, "cacerts");
		}
		System.out.println("Loading KeyStore " + file + "...");
		try {
			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);
			try {
				SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
				socket.setSoTimeout(10000);
				System.out.println("Starting SSL handshake...");
				socket.startHandshake();
				socket.close();
				System.out.println("No errors, certificate is already trusted");
			} catch (Exception e) {
				e.printStackTrace();
			}

			X509Certificate[] chain = tm.chain;
			if (chain == null) {
				return;
			}

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					System.in));
			MessageDigest sha1 = MessageDigest.getInstance("SHA1");
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			for (int i = 0; i < chain.length; i++) {
				X509Certificate cert = chain[i];
				sha1.update(cert.getEncoded());
				md5.update(cert.getEncoded());
			}
			// 默认证书链第一个
			int index = 0;
			X509Certificate cert = chain[index];
			String alias = host + "-" + (index + 1);
			ks.setCertificateEntry(alias, cert);

			// keyStore保存到文件jssecacerts
			File jssecacerts = new File(dir, "jssecacerts");
			OutputStream out = new FileOutputStream(jssecacerts);
			ks.store(out, passphrase);
			out.close();

			System.out.println("-----打印cert-----");
			System.out.println(cert);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

	private 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 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);
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值