zoukankan      html  css  js  c++  java
  • 解决PKIX:unable to find valid certification path to requested target 的问题

    这两天在twitter服务器上忽然遇到这样的异常:

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

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

    Java类已经无法下载了。。。。历经N次的google,终于找到该文件了,不敢独享,记录于此。


    问题的根本是:

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

    解决问题方法:

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


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

    1. /* 
    2.  * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved. 
    3.  * 
    4.  * Redistribution and use in source and binary forms, with or without 
    5.  * modification, are permitted provided that the following conditions 
    6.  * are met: 
    7.  * 
    8.  *   - Redistributions of source code must retain the above copyright 
    9.  *     notice, this list of conditions and the following disclaimer. 
    10.  * 
    11.  *   - Redistributions in binary form must reproduce the above copyright 
    12.  *     notice, this list of conditions and the following disclaimer in the 
    13.  *     documentation and/or other materials provided with the distribution. 
    14.  * 
    15.  *   - Neither the name of Sun Microsystems nor the names of its 
    16.  *     contributors may be used to endorse or promote products derived 
    17.  *     from this software without specific prior written permission. 
    18.  * 
    19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
    20.  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
    21.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
    22.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
    23.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
    24.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
    25.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
    26.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
    27.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
    28.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
    29.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    30.  */  
    31.   
    32. import java.io.BufferedReader;  
    33. import java.io.File;  
    34. import java.io.FileInputStream;  
    35. import java.io.FileOutputStream;  
    36. import java.io.InputStream;  
    37. import java.io.InputStreamReader;  
    38. import java.io.OutputStream;  
    39. import java.security.KeyStore;  
    40. import java.security.MessageDigest;  
    41. import java.security.cert.CertificateException;  
    42. import java.security.cert.X509Certificate;  
    43.   
    44. import javax.net.ssl.SSLContext;  
    45. import javax.net.ssl.SSLException;  
    46. import javax.net.ssl.SSLSocket;  
    47. import javax.net.ssl.SSLSocketFactory;  
    48. import javax.net.ssl.TrustManager;  
    49. import javax.net.ssl.TrustManagerFactory;  
    50. import javax.net.ssl.X509TrustManager;  
    51.   
    52. public class InstallCert {  
    53.   
    54.     public static void main(String[] args) throws Exception {  
    55.         String host;  
    56.         int port;  
    57.         char[] passphrase;  
    58.         if ((args.length == 1) || (args.length == 2)) {  
    59.             String[] c = args[0].split(":");  
    60.             host = c[0];  
    61.             port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);  
    62.             String p = (args.length == 1) ? "changeit" : args[1];  
    63.             passphrase = p.toCharArray();  
    64.         } else {  
    65.             System.out  
    66.                     .println("Usage: java InstallCert <host>[:port] [passphrase]");  
    67.             return;  
    68.         }  
    69.   
    70.         File file = new File("jssecacerts");  
    71.         if (file.isFile() == false) {  
    72.             char SEP = File.separatorChar;  
    73.             File dir = new File(System.getProperty("java.home") + SEP + "lib"  
    74.                     + SEP + "security");  
    75.             file = new File(dir, "jssecacerts");  
    76.             if (file.isFile() == false) {  
    77.                 file = new File(dir, "cacerts");  
    78.             }  
    79.         }  
    80.         System.out.println("Loading KeyStore " + file + "...");  
    81.         InputStream in = new FileInputStream(file);  
    82.         KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());  
    83.         ks.load(in, passphrase);  
    84.         in.close();  
    85.   
    86.         SSLContext context = SSLContext.getInstance("TLS");  
    87.         TrustManagerFactory tmf = TrustManagerFactory  
    88.                 .getInstance(TrustManagerFactory.getDefaultAlgorithm());  
    89.         tmf.init(ks);  
    90.         X509TrustManager defaultTrustManager = (X509TrustManager) tmf  
    91.                 .getTrustManagers()[0];  
    92.         SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);  
    93.         context.init(null, new TrustManager[] { tm }, null);  
    94.         SSLSocketFactory factory = context.getSocketFactory();  
    95.   
    96.         System.out  
    97.                 .println("Opening connection to " + host + ":" + port + "...");  
    98.         SSLSocket socket = (SSLSocket) factory.createSocket(host, port);  
    99.         socket.setSoTimeout(10000);  
    100.         try {  
    101.             System.out.println("Starting SSL handshake...");  
    102.             socket.startHandshake();  
    103.             socket.close();  
    104.             System.out.println();  
    105.             System.out.println("No errors, certificate is already trusted");  
    106.         } catch (SSLException e) {  
    107.             System.out.println();  
    108.             e.printStackTrace(System.out);  
    109.         }  
    110.   
    111.         X509Certificate[] chain = tm.chain;  
    112.         if (chain == null) {  
    113.             System.out.println("Could not obtain server certificate chain");  
    114.             return;  
    115.         }  
    116.   
    117.         BufferedReader reader = new BufferedReader(new InputStreamReader(  
    118.                 System.in));  
    119.   
    120.         System.out.println();  
    121.         System.out.println("Server sent " + chain.length + " certificate(s):");  
    122.         System.out.println();  
    123.         MessageDigest sha1 = MessageDigest.getInstance("SHA1");  
    124.         MessageDigest md5 = MessageDigest.getInstance("MD5");  
    125.         for (int i = 0; i < chain.length; i++) {  
    126.             X509Certificate cert = chain[i];  
    127.             System.out.println(" " + (i + 1) + " Subject "  
    128.                     + cert.getSubjectDN());  
    129.             System.out.println("   Issuer  " + cert.getIssuerDN());  
    130.             sha1.update(cert.getEncoded());  
    131.             System.out.println("   sha1    " + toHexString(sha1.digest()));  
    132.             md5.update(cert.getEncoded());  
    133.             System.out.println("   md5     " + toHexString(md5.digest()));  
    134.             System.out.println();  
    135.         }  
    136.   
    137.         System.out  
    138.                 .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");  
    139.         String line = reader.readLine().trim();  
    140.         int k;  
    141.         try {  
    142.             k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;  
    143.         } catch (NumberFormatException e) {  
    144.             System.out.println("KeyStore not changed");  
    145.             return;  
    146.         }  
    147.   
    148.         X509Certificate cert = chain[k];  
    149.         String alias = host + "-" + (k + 1);  
    150.         ks.setCertificateEntry(alias, cert);  
    151.   
    152.         OutputStream out = new FileOutputStream("jssecacerts");  
    153.         ks.store(out, passphrase);  
    154.         out.close();  
    155.   
    156.         System.out.println();  
    157.         System.out.println(cert);  
    158.         System.out.println();  
    159.         System.out  
    160.                 .println("Added certificate to keystore 'jssecacerts' using alias '"  
    161.                         + alias + "'");  
    162.     }  
    163.   
    164.     private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();  
    165.   
    166.     private static String toHexString(byte[] bytes) {  
    167.         StringBuilder sb = new StringBuilder(bytes.length * 3);  
    168.         for (int b : bytes) {  
    169.             b &= 0xff;  
    170.             sb.append(HEXDIGITS[b >> 4]);  
    171.             sb.append(HEXDIGITS[b & 15]);  
    172.             sb.append(' ');  
    173.         }  
    174.         return sb.toString();  
    175.     }  
    176.   
    177.     private static class SavingTrustManager implements X509TrustManager {  
    178.   
    179.         private final X509TrustManager tm;  
    180.         private X509Certificate[] chain;  
    181.   
    182.         SavingTrustManager(X509TrustManager tm) {  
    183.             this.tm = tm;  
    184.         }  
    185.   
    186.         public X509Certificate[] getAcceptedIssuers() {  
    187.             throw new UnsupportedOperationException();  
    188.         }  
    189.   
    190.         public void checkClientTrusted(X509Certificate[] chain, String authType)  
    191.                 throws CertificateException {  
    192.             throw new UnsupportedOperationException();  
    193.         }  
    194.   
    195.         public void checkServerTrusted(X509Certificate[] chain, String authType)  
    196.                 throws CertificateException {  
    197.             this.chain = chain;  
    198.             tm.checkServerTrusted(chain, authType);  
    199.         }  
    200.     }  
    201.   
    202. }  


    编译InstallCert.java,然后执行:java InstallCert hostname,比如:
    java InstallCert www.twitter.com
    会看到如下信息:

    1. java InstallCert www.twitter.com  
    2. Loading KeyStore /usr/java/jdk1.6.0_16/jre/lib/security/cacerts...  
    3. Opening connection to www.twitter.com:443...  
    4. Starting SSL handshake...  
    5.   
    6. 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  
    7.     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)  
    8.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1476)  
    9.     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)  
    10.     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)  
    11.     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:846)  
    12.     at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)  
    13.     at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)  
    14.     at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)  
    15.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:815)  
    16.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1025)  
    17.     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1038)  
    18.     at InstallCert.main(InstallCert.java:63)  
    19. Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target  
    20.     at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)  
    21.     at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:145)  
    22.     at sun.security.validator.Validator.validate(Validator.java:203)  
    23.     at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)  
    24.     at InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:158)  
    25.     at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)  
    26.     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:839)  
    27.     ... 7 more  
    28. Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target  
    29.     at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)  
    30.     at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)  
    31.     at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)  
    32.     ... 13 more  
    33.   
    34. Server sent 2 certificate(s):  
    35.   
    36.  1 Subject CN=www.twitter.com, O=example.com, C=US  
    37.    Issuer  CN=Certificate Shack, O=example.com, C=US  
    38.    sha1    2e 7f 76 9b 52 91 09 2e 5d 8f 6b 61 39 2d 5e 06 e4 d8 e9 c7   
    39.    md5     dd d1 a8 03 d7 6c 4b 11 a7 3d 74 28 89 d0 67 54   
    40.   
    41.  2 Subject CN=Certificate Shack, O=example.com, C=US  
    42.    Issuer  CN=Certificate Shack, O=example.com, C=US  
    43.    sha1    fb 58 a7 03 c4 4e 3b 0e e3 2c 40 2f 87 64 13 4d df e1 a1 a6   
    44.    md5     72 a0 95 43 7e 41 88 18 ae 2f 6d 98 01 2c 89 68   
    45.   
    46. 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,证书才能生效。

  • 相关阅读:
    selenium Grid2 分布式自动化测试环境搭建
    Python Appium 开启Android测试之路
    C#导出数据到CSV和EXCEL文件时数字文本被转义的解决方法
    浅谈 DML、DDL、DCL的区别
    让EntityFramework6支持SQLite
    System.Drawing.Color的颜色对照表
    清除远程桌面连接记录和SQLSERVER 连接记录的办法
    Jquery操作select选项集合!
    asp.net 模拟CURL调用微信公共平台API 上传下载多媒体文件接口
    Log4net 根据日志类别保存到不同的文件,并按照日期生成不同文件名称
  • 原文地址:https://www.cnblogs.com/sikewang/p/5670813.html
Copyright © 2011-2022 走看看