2013-02-28 2 views
1

Я строю сервер, который должен вызывать два веб-сервиса. Веб-службы имеют один и тот же сертификат 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 запроса I не имеют проблем, но с запросом SOAP httpsUrlConnection.connect(); throws Не удалось создать путь PKIX: sun.security.provider.certpath.SunCertP athBuilderException: не удалось найти допустимый путь сертификации для запрошенной цели

ответ

0

Вот как создать контекст ssl для соединения HTTPS.

 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

+0

... Я не нашел IOUtils.closeQuietly (in); метод. – Ging3r

+0

Config.getString (Config.KEYSTORE_PATH) - свойство в моей конфигурации. В вашем случае это 'PropConfig.getProperty (" cer.p12 ")'. HTTPS_SERVER_CERT - путь к серверу certifiacte. – user1516873

Смежные вопросы