2013-02-28 87 views
1

我正在構建一個服務器,它必須調用兩個Web服務。 Webservices具有相同的CA證書(PKCS12)。SOAP - PKIX路徑構建失敗

第一個通過GET接收請求,另一個通過SOAP調用。

遵循的守則的一部分,致力於爲GET請求

  InputStream inputStream = null; 

      // is https protocol? 
      if (url.getProtocol().toLowerCase().equals("https")) { 

       trustAllHosts(); 
       // create connection 
       HttpsURLConnection httpsUrlConnection = null; 
       if(proxy != null){ 
        httpsUrlConnection = (HttpsURLConnection) url.openConnection(proxy); 
       } else { 
        httpsUrlConnection = (HttpsURLConnection) url.openConnection(); 
       } 
       // set the check to: do not verify 
       httpsUrlConnection.setHostnameVerifier(new HostnameVerifier() { 
        @Override 
        public boolean verify(String hostname, SSLSession session) { 
         return true; 
        } 
       }); 

       setHeaders(httpsUrlConnection, headers);  

       //set del certificato 

       log.debug("set certificate for get..."); 
       File cerp12 = new File(Utils.getWebAppLocalPath(),"WEB-INF"+String.valueOf(File.separatorChar)+PropConfig.getProperty("cer.p12")); 
       ((HttpsURLConnection) httpsUrlConnection).setSSLSocketFactory(security(cerp12,PropConfig.getProperty("cer.pwd"))); 
       httpsUrlConnection.connect(); 

       inputStream = httpsUrlConnection.getInputStream(); 

      } else { 
       HttpURLConnection httpUrlConnection = null; 
       if(proxy != null){ 
        httpUrlConnection = (HttpURLConnection) url.openConnection(proxy); 
       } else { 
        httpUrlConnection = (HttpURLConnection) url.openConnection(); 
       } 

       setHeaders(httpUrlConnection, headers);  

       inputStream = httpUrlConnection.getInputStream(); 
      } 

      in = new BufferedReader(new InputStreamReader(inputStream)); 

      String inputLine; 
      while ((inputLine = in.readLine()) != null) { 
       result.append(inputLine); 
      } 

連接,這部分是SOAP請求

  InputStream inputStream = null; 

      // is https protocol? 
      if (url.getProtocol().toLowerCase().equals("https")) { 

       trustAllHosts(); 
       // create connection 
       HttpsURLConnection httpsUrlConnection = null; 
       if(proxy != null){ 
        httpsUrlConnection = (HttpsURLConnection) url.openConnection(proxy); 
       } else { 
        httpsUrlConnection = (HttpsURLConnection) url.openConnection(); 
       } 
       // set the check to: do not verify 
       httpsUrlConnection.setHostnameVerifier(new HostnameVerifier() { 
        @Override 
        public boolean verify(String hostname, SSLSession session) { 
         return true; 
        } 
       }); 

       setHeaders(httpsUrlConnection, headers);  

       //set del certificato 

       log.debug("set certificate for get..."); 
       File cerp12 = new File(Utils.getWebAppLocalPath(),"WEB-INF"+String.valueOf(File.separatorChar)+PropConfig.getProperty("cer.p12")); 
       ((HttpsURLConnection) httpsUrlConnection).setSSLSocketFactory(security(cerp12,PropConfig.getProperty("cer.pwd"))); 
       httpsUrlConnection.connect(); 

       inputStream = httpsUrlConnection.getInputStream(); 

      } else { 
       HttpURLConnection httpUrlConnection = null; 
       if(proxy != null){ 
        httpUrlConnection = (HttpURLConnection) url.openConnection(proxy); 
       } else { 
        httpUrlConnection = (HttpURLConnection) url.openConnection(); 
       } 

       setHeaders(httpUrlConnection, headers);  

       inputStream = httpUrlConnection.getInputStream(); 
      } 

      in = new BufferedReader(new InputStreamReader(inputStream)); 

      String inputLine; 
      while ((inputLine = in.readLine()) != null) { 
       result.append(inputLine); 
      } 

的代碼幾乎是相同的

與GET請求我沒有問題,但有SOAP請求httpsUrlConnection.connect();拋出 PKIX路徑構建失敗:sun.security.provider.certpath.SunCertP athBuilderException:無法找到要求的目標的有效證書路徑

回答

0

以下是如何爲HTTPS連接創建SSL上下文。

 SSLSocketFactory socketFactory = createSSLContext().getSocketFactory(); 

     HttpsURLConnection connection = (HttpsURLConnection) (url).openConnection(); 
     connection.setSSLSocketFactory(socketFactory); 

創建SSL上下文的方法。請注意,它從.pem文件(x509格式)和.p12(pkcs12格式)的客戶端證書加載根服務器證書。如果服務器不需要客戶端證書,則將密鑰管理器傳遞給null。如果權限頒發的服務器證書(已在$ JRE_HOME/lib/security/cacerts中)作爲信任管理器傳遞null。

還有一點需要注意:在.pem文件中,您應該將根證書存儲在服務器證書的PKIX路徑中。例如,github.com該站點具有PKIX路徑CN = github.com - >CN = DigiCert High Assurance EV CA-1 - >CN = DigiCert High Assurance EV Root CA - >CN = GTE CyberTrust Global Root。所以你存儲GTE CyberTrust Global Root

private final SSLContext createSSLContext() 
      throws NoSuchAlgorithmException, KeyStoreException, 
      CertificateException, IOException, 
      UnrecoverableKeyException, KeyManagementException { 


     KeyStore keyStore = KeyStore.getInstance("PKCS12"); 

     FileInputStream fis = null; 
     try { 
      fis = new FileInputStream(new File(Config.getString(Config.KEYSTORE_PATH))); 
     } catch (Exception ex) { 
      throw new IOException("not found keystore file: " Config.getString(Config.KEYSTORE_PATH), ex); 
     } 
     try{ 
      keyStore.load(fis, Config.getString(Config.KEYSTORE_PASSWORD).toCharArray()); 
     }finally { 
      IOUtils.closeQuietly(fis); 
     } 
     CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
     FileInputStream in = new FileInputStream(Config.getString(Config.HTTPS_SERVER_CERT)); 
     KeyStore trustStore = KeyStore.getInstance("JKS"); 
     trustStore.load(null); 
     try { 
      X509Certificate cacert = (X509Certificate) cf.generateCertificate(in); 
      trustStore.setCertificateEntry("alias", cacert); 
     } finally { 
      IOUtils.closeQuietly(in); 
     } 

     TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 
     tmf.init(trustStore); 

     KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 
     kmf.init(keyStore, Config.getString(Config.KEYSTORE_PASSWORD).toCharArray()); 

     SSLContext sslContext = SSLContext.getInstance("SSL"); 
     sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); 
     return sslContext; 
    } 
+0

感謝對響應,只有一件事:什麼是'Config.KEYSTORE_PATH'? 'p12'路徑或'.keystore'路徑?而且,什麼是「Config.HTTPS_SERVER_CERT」? – Ging3r 2013-03-05 09:12:26

+0

...我不'找到IOUtils.closeQuietly(in);方法.. – Ging3r 2013-03-05 09:18:41

+0

Config.getString(Config.KEYSTORE_PATH) - 我的配置中的屬性。在你的情況下,它是'PropConfig.getProperty(「cer.p12」)'。 HTTPS_SERVER_CERT - 服務器認證的路徑。 – user1516873 2013-03-05 09:31:12

相關問題