首页 文章

PKIX路径构建失败:在 生产环境 服务器中不起作用 . 它不信任证书

提问于
浏览
1

当我在 生产环境 环境中部署它时,我的J2EE应用程序抛出异常 . 我已经尝试过keytool生成的自签名证书,但它没有任何意义

JDK: (Oracle JDK) java version "1.7.0_80" Tomcat :7.0.55

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

此应用程序与需要通过HTTPS通信的API进行通信 . 以下是代码段:

public  String reqSender() throws Exception 
{

String inputLine="xxxxx";
String refreshToken="addddddd";
String httpsURL = "https://mifc.xxx.lk/xxx/token?grant_type=refresh_token&refresh_token="
                        + refreshToken + "&scope=PRODUCTION";



URL myurl = new URL(httpsURL);

HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
con.setRequestMethod("POST");

con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("Authorization","Basic YxsdsdsfdfsfsdsdsdSncxU0dlQXJPY3F1Q1JndXc3bU1h");


InputStream ins = con.getInputStream();


InputStreamReader isr = new InputStreamReader(ins);


    try (BufferedReader in = new BufferedReader(isr)) {

        while ((inputLine = in.readLine()) != null)
        {
            System.out.println(inputLine);
        }   }
    return inputLine;}

1 回答

  • 1

    问题的原因:客户端无法信任我们尝试访问的服务器端证书 . 因此我写了使用HttpsURLConnection扩展HttpURLConnection和X509TrustManager进行身份验证 . 还使用单独的类“SSLCert”来信任证书 . 这样客户端就可以信任证书并按预期进行通信 .

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import static java.lang.Math.log;
    import static java.lang.System.out;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import org.json.JSONObject;
    
    import java.security.GeneralSecurityException;
    import java.security.SecureRandom;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    
    
    
    public String reqSender()() throws Exception {
            String acessToken = null;
            String rfshToken = null;
            double expiresIn = 0.0D;
            int x = 0;
            SSLCert.trustAllHostnames();
            SSLCert.trustAllHttpsCertificates();
            //DbCon con = new DbCon();
    
            try {
                String refreshToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
                System.out.println(refreshToken);
                System.out.println("");
                System.out.println("Calling web service...");
    
                URL url = new URL(
                        "https://mifxx.xxxxx.lk/apicall/token?grant_type=refresh_token&refresh_token="
                        + refreshToken + "&scope=PRODUCTION");
                System.out.println("web service called" + url.toString());
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Content-Type",
                        "application/x-www-form-urlencoded");
                conn.setRequestProperty(
                        "Authorization",
                        "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1JndXc3bU1h");
        enter code here
                /////start
                HttpsURLConnection conHttps = (HttpsURLConnection) conn;
                TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
    
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
    
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
    
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }};
    
                HostnameVerifier allHostsValid = new HostnameVerifier() {
                    @Override
                    public boolean verify(String arg0, SSLSession arg1) {
                        return true;
                    }
                };
    
                // Install the all-trusting trust manager
                try {
                    SSLContext sc = SSLContext.getInstance("SSL");
                    sc.init(null, trustAllCerts, new java.security.SecureRandom());
                    HttpsURLConnection.setDefaultSSLSocketFactory(sc
                            .getSocketFactory());
                    HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
                    conn = conHttps;
                } catch (Exception e) {
                }
    
                /////End
                x = conn.getResponseCode();
                System.out.println(conn.getResponseCode() + "CODE");
                if (conn.getResponseCode() != 200) {
                    throw new RuntimeException("Failed : HTTP error code : "
                            + conn.getResponseCode());
                }
    
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        conn.getInputStream()));
    
                System.out.println("Output from Server ....");
                String output = null;
                while ((output = br.readLine()) != null) {
                    System.out.println(output);
    
                    JSONObject obj = new JSONObject(output);
                    String defult = obj.getString("scope");
                    String tokenType = obj.getString("token_type");
                    expiresIn = obj.getDouble("expires_in");
                    rfshToken = obj.getString("refresh_token");
                    acessToken = obj.getString("access_token");
    
                    System.out.println("");
                    System.out.println("-------------------------");
                    System.out.println("Access Token :" + acessToken);
                    System.out.println("Refresh Token :" + rfshToken);
                    System.out.println("Token Type :" + tokenType);
                    System.out.println("Scope :" + defult);
                    System.out.println("Expiration time: " + expiresIn);
                    System.out.println("-------------------------");
                    System.out.println("");
                }
    
                conn.disconnect();
            } catch (MalformedURLException e) {
                //log.error(e);
                e.printStackTrace();
            } catch (IOException e) {
                //log.error(e);
                e.printStackTrace();
            }
            return rfshToken;
        }
    

    下课是SSLCert

    SSLCert class
    
    import java.security.GeneralSecurityException;
     import java.security.SecureRandom;
     import java.security.cert.X509Certificate;
     import javax.net.ssl.HostnameVerifier;
     import javax.net.ssl.HttpsURLConnection;
     import javax.net.ssl.SSLContext;
     import javax.net.ssl.TrustManager;
     import javax.net.ssl.X509TrustManager;
    
     /**
      * This class provide various static methods that relax X509 certificate and 
      * hostname verification while using the SSL over the HTTP protocol.
      *
      * 
      */
     public final class SSLCert {
    
       /**
        * Hostname verifier for the Sun's deprecated API.
        *
        * @deprecated see {@link #_hostnameVerifier}.
        */
       private static com.sun.net.ssl.HostnameVerifier __hostnameVerifier;
       /**
        * Thrust managers for the Sun's deprecated API.
        *
        * @deprecated see {@link #_trustManagers}.
        */
       private static com.sun.net.ssl.TrustManager[] __trustManagers;
       /**
        * Hostname verifier.
        */
       private static HostnameVerifier _hostnameVerifier;
       /**
        * Thrust managers.
        */
       private static TrustManager[] _trustManagers;
    
    
       /**
        * Set the default Hostname Verifier to an instance of a fake class that 
        * trust all hostnames. This method uses the old deprecated API from the 
        * com.sun.ssl package.
        *
        * @deprecated see {@link #_trustAllHostnames()}.
        */
       private static void __trustAllHostnames() {
           // Create a trust manager that does not validate certificate chains
           if(__hostnameVerifier == null) {
               __hostnameVerifier = new _FakeHostnameVerifier();
           } // if
           // Install the all-trusting host name verifier
           com.sun.net.ssl.HttpsURLConnection.
               setDefaultHostnameVerifier(__hostnameVerifier);
       } // __trustAllHttpsCertificates
    
       /**
        * Set the default X509 Trust Manager to an instance of a fake class that 
        * trust all certificates, even the self-signed ones. This method uses the 
        * old deprecated API from the com.sun.ssl package.
        *
        * @deprecated see {@link #_trustAllHttpsCertificates()}.
        */
       private static void __trustAllHttpsCertificates() {
           com.sun.net.ssl.SSLContext context;
    
           // Create a trust manager that does not validate certificate chains
           if(__trustManagers == null) {
               __trustManagers = new com.sun.net.ssl.TrustManager[] 
                   {new _FakeX509TrustManager()};
           } // if
           // Install the all-trusting trust manager
           try {
               context = com.sun.net.ssl.SSLContext.getInstance("SSL");
               context.init(null, __trustManagers, new SecureRandom());
           } catch(GeneralSecurityException gse) {
               throw new IllegalStateException(gse.getMessage());
           } // catch
           com.sun.net.ssl.HttpsURLConnection.
               setDefaultSSLSocketFactory(context.getSocketFactory());
       } // __trustAllHttpsCertificates
    
       /**
        * Return true if the protocol handler property java.
        * protocol.handler.pkgs is set to the Sun's com.sun.net.ssl.
        * internal.www.protocol deprecated one, false 
        * otherwise.
        *
        * @return                true if the protocol handler 
        * property is set to the Sun's deprecated one, false 
        * otherwise.
        */
       private static boolean isDeprecatedSSLProtocol() {
           return("com.sun.net.ssl.internal.www.protocol".equals(System.
               getProperty("java.protocol.handler.pkgs")));
       } // isDeprecatedSSLProtocol
    
       /**
        * Set the default Hostname Verifier to an instance of a fake class that 
        * trust all hostnames.
        */
       private static void _trustAllHostnames() {
           // Create a trust manager that does not validate certificate chains
           if(_hostnameVerifier == null) {
               _hostnameVerifier = new FakeHostnameVerifier();
           } // if
             // Install the all-trusting host name verifier:
           HttpsURLConnection.setDefaultHostnameVerifier(_hostnameVerifier);
       } // _trustAllHttpsCertificates
    
       /**
        * Set the default X509 Trust Manager to an instance of a fake class that 
        * trust all certificates, even the self-signed ones.
        */
       private static void _trustAllHttpsCertificates() {
           SSLContext context;
    
           // Create a trust manager that does not validate certificate chains
           if(_trustManagers == null) {
               _trustManagers = new TrustManager[] {new FakeX509TrustManager()};
           } // if
           // Install the all-trusting trust manager:
           try {
           context = SSLContext.getInstance("SSL");
           context.init(null, _trustManagers, new SecureRandom());
           } catch(GeneralSecurityException gse) {
               throw new IllegalStateException(gse.getMessage());
           } // catch
           HttpsURLConnection.setDefaultSSLSocketFactory(context.
               getSocketFactory());
       } // _trustAllHttpsCertificates
    
       /**
        * Set the default Hostname Verifier to an instance of a fake class that 
        * trust all hostnames.
        */
       public static void trustAllHostnames() {
           // Is the deprecated protocol setted?
           if(isDeprecatedSSLProtocol()) {
               __trustAllHostnames();
           } else {
               _trustAllHostnames();
           } // else
       } // trustAllHostnames
    
       /**
        * Set the default X509 Trust Manager to an instance of a fake class that 
        * trust all certificates, even the self-signed ones.
        */
       public static void trustAllHttpsCertificates() {
           // Is the deprecated protocol setted?
           if(isDeprecatedSSLProtocol()) {
               __trustAllHttpsCertificates();
           } else {
               _trustAllHttpsCertificates();
           } // else
       } // trustAllHttpsCertificates
    
       /**
        * This class implements a fake hostname verificator, trusting any host 
        * name. This class uses the old deprecated API from the com.sun.
        * ssl package.
        *
        * 
        *
        * @deprecated see {@link SSLCert.FakeHostnameVerifier}.
        */
       public static class _FakeHostnameVerifier 
           implements com.sun.net.ssl.HostnameVerifier {
    
           /**
            * Always return true, indicating that the host name is an 
            * acceptable match with the server's authentication scheme.
            *
            * @param hostname        the host name.
            * @param session         the SSL session used on the connection to 
            * host.
            * @return                the true boolean value 
            * indicating the host name is trusted.
            */
           public boolean verify(String hostname, String session) {
               return(true);
           } // verify
       } // _FakeHostnameVerifier
    
    
       /**
        * This class allow any X509 certificates to be used to authenticate the 
        * remote side of a secure socket, including self-signed certificates. This 
        * class uses the old deprecated API from the com.sun.ssl 
        * package.
        *
        * 
        *
        * @deprecated see {@link SSLCert.FakeX509TrustManager}.
        */
       public static class _FakeX509TrustManager 
           implements com.sun.net.ssl.X509TrustManager {
    
           /**
            * Empty array of certificate authority certificates.
            */
           private static final X509Certificate[] _AcceptedIssuers = 
               new X509Certificate[] {};
    
    
           /**
            * Always return true, trusting for client SSL 
            * chain peer certificate chain.
            *
            * @param chain           the peer certificate chain.
            * @return                the true boolean value 
            * indicating the chain is trusted.
            */
           public boolean isClientTrusted(X509Certificate[] chain) {
               return(true);
           } // checkClientTrusted
    
           /**
            * Always return true, trusting for server SSL 
            * chain peer certificate chain.
            *
            * @param chain           the peer certificate chain.
            * @return                the true boolean value 
            * indicating the chain is trusted.
            */
           public boolean isServerTrusted(X509Certificate[] chain) {
               return(true);
           } // checkServerTrusted
    
           /**
            * Return an empty array of certificate authority certificates which 
            * are trusted for authenticating peers.
            *
            * @return                a empty array of issuer certificates.
            */
           public X509Certificate[] getAcceptedIssuers() {
               return(_AcceptedIssuers);
           } // getAcceptedIssuers
       } // _FakeX509TrustManager
    
    
       /**
        * This class implements a fake hostname verificator, trusting any host 
        * name.
        *
        * 
        */
       public static class FakeHostnameVerifier implements HostnameVerifier {
    
           /**
            * Always return true, indicating that the host name is 
            * an acceptable match with the server's authentication scheme.
            *
            * @param hostname        the host name.
            * @param session         the SSL session used on the connection to 
            * host.
            * @return                the true boolean value 
            * indicating the host name is trusted.
            */
           public boolean verify(String hostname, 
               javax.net.ssl.SSLSession session) {
               return(true);
           } // verify
       } // FakeHostnameVerifier
    
    
       /**
        * This class allow any X509 certificates to be used to authenticate the 
        * remote side of a secure socket, including self-signed certificates.
        *
        * 
        */
       public static class FakeX509TrustManager implements X509TrustManager {
    
           /**
            * Empty array of certificate authority certificates.
            */
           private static final X509Certificate[] _AcceptedIssuers = 
               new X509Certificate[] {};
    
    
           /**
            * Always trust for client SSL chain peer certificate 
            * chain with any authType authentication types.
            *
            * @param chain           the peer certificate chain.
            * @param authType        the authentication type based on the client 
            * certificate.
            */
           public void checkClientTrusted(X509Certificate[] chain, 
               String authType) {
           } // checkClientTrusted
    
           /**
            * Always trust for server SSL chain peer certificate 
            * chain with any authType exchange algorithm types.
            *
            * @param chain           the peer certificate chain.
            * @param authType        the key exchange algorithm used.
            */
           public void checkServerTrusted(X509Certificate[] chain, 
               String authType) {
           } // checkServerTrusted
    
           /**
            * Return an empty array of certificate authority certificates which 
            * are trusted for authenticating peers.
            *
            * @return                a empty array of issuer certificates.
            */
           public X509Certificate[] getAcceptedIssuers() {
               return(_AcceptedIssuers);
           } // getAcceptedIssuers
       } // FakeX509TrustManager
     } // SSLCert
    

相关问题