解決PKIX path building failed的問題
阿新 • • 發佈:2019-02-16
方法一:使用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); } } }