2016-04-16 65 views
1

我需要使用特定的SSL密鑰庫(.pfx或.jks)進行HTTP調用。我正在使用SAAJ實現來進行SOAP調用。如何將密鑰庫與SAAJ SOAP調用相關聯

以下是我所關注的步驟。 1.設置系統屬性來讀取密鑰庫

System.setProperty("javax.net.ssl.trustStore",path to cacerts); 
System.setProperty("javax.net.ssl.trustStorePassword",password); 
System.setProperty("javax.net.ssl.keyStore",path to keystore (.pfx file)); 
System.setProperty("javax.net.ssl.keyStorePassword",keystorepassword); 
System.setProperty("javax.net.ssl.keyStoreType",(PKC12 or JKS)); 
  • 然後我信任所有證書

    static public void doTrustToCertificates() throws Exception { 
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider()); 
        TrustManager[] trustAllCerts = new TrustManager[] { 
        new X509TrustManager() { 
        public X509Certificate[] getAcceptedIssuers() { 
        return null; 
        } 
    
        public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { 
        return; 
        } 
    
        public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { 
        return; 
        } 
        } 
        }; 
    
        SSLContext sc = SSLContext.getInstance("SSL"); 
        sc.init(null, trustAllCerts, new SecureRandom()); 
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 
        HostnameVerifier hv = new HostnameVerifier() { 
        public boolean verify(String urlHostName, SSLSession session) { 
        if (!urlHostName.equalsIgnoreCase(session.getPeerHost())) { 
        System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'."); 
        } 
        return true; 
        } 
        }; 
        HttpsURLConnection.setDefaultHostnameVerifier(hv); 
    

    }

  • 然後我嘗試創建連接和呼叫

     // Send SOAP Message to SOAP Server 
         URL url= new URL(endpointURL); 
         // Create SOAP Connection 
         SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); 
         SOAPConnection soapConnection = soapConnectionFactory.createConnection(); 
         SOAPMessage soapResponse; 
         try{ 
          soapResponse = soapConnection.call(message, url); 
         } 
         finally{ 
          if (soapConnection!=null){ 
           try { 
            soapConnection.close(); 
           } catch (SOAPException soape){ 
            log.info(" Failed to close SOAPConnection. Error " +soape.getMessage()); 
           } 
          } 
         } 
    
  • 但是,每次我嘗試這個時,我都會收到一個錯誤,指出由於PKIX路徑構建失敗,消息發送失敗。我需要知道我是否按照正確的方法進行HTTPS調用。此外,我的需要是以編程方式關聯證書,而不是使用keytool。

    部分堆棧跟蹤

    com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message send failed 
        at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown Source) 
        at fASTest.FunctionsKeyWord.InvokeHTTPsSOAPRequest(FunctionsKeyWord.java:319) 
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
        at java.lang.reflect.Method.invoke(Unknown Source) 
        at fASTest.FunctionsKeyWord.InvokeActions(FunctionsKeyWord.java:125) 
        at fASTest.DriverTestCase.ExecuteTestCaseDriver(DriverTestCase.java:244) 
        at fASTest.DriverSuite.ExecuteSuiteDriver(DriverSuite.java:134) 
        at fASTest.CallScript.main(CallScript.java:49) 
    Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Message send failed 
        at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown Source) 
        ... 10 more 
    Caused by: 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 
        at sun.security.ssl.Alerts.getSSLException(Unknown Source) 
        at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source) 
        at sun.security.ssl.Handshaker.fatalSE(Unknown Source) 
        at sun.security.ssl.Handshaker.fatalSE(Unknown Source) 
        at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source) 
        at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source) 
        at sun.security.ssl.Handshaker.processLoop(Unknown Source) 
        at sun.security.ssl.Handshaker.process_record(Unknown Source) 
        at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source) 
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source) 
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) 
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source) 
        at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source) 
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source) 
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(Unknown Source) 
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source) 
        at com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl.getOutputStream(Unknown Source) 
        ... 11 more 
    Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
        at sun.security.validator.PKIXValidator.doBuild(Unknown Source) 
        at sun.security.validator.PKIXValidator.engineValidate(Unknown Source) 
        at sun.security.validator.Validator.validate(Unknown Source) 
        at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source) 
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source) 
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source) 
        ... 24 more 
    Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
        at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source) 
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source) 
        at java.security.cert.CertPathBuilder.build(Unknown Source) 
        ... 30 more 
    

    回答

    0

    基本上,你需要更換doTrustToCertificates內)用下面的代碼(方法:只需在連接之前)方法

    static public void doTrustToCertificates() throws Exception 
    { 
        // Set truststore that contains root/intermediary certs 
        System.setProperty("javax.net.ssl.trustStore", "C:\\cert\\trusted.jks"); 
        System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
    
        // Set keystore that contains private key 
        File pKeyFile = new File("C:\\cert\\privatekey.pfx"); 
        String pKeyPassword = "Password01"; 
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); 
        KeyStore keyStore = KeyStore.getInstance("PKCS12"); 
        InputStream keyInput = new FileInputStream(pKeyFile); 
        keyStore.load(keyInput, pKeyPassword.toCharArray()); 
        keyInput.close(); 
        keyManagerFactory.init(keyStore, pKeyPassword.toCharArray()); 
    
        // Set ssl context with private key and truststore details 
        SSLContext sc = SSLContext.getInstance("TLSv1"); 
        sc.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom()); 
        SSLSocketFactory sockFact = sc.getSocketFactory(); 
    
        // Add ssl context to https connection 
        HttpsURLConnection.setDefaultSSLSocketFactory(sockFact); 
    }  
    

    你再調用doTrustToCertificates( .call()方法如下:

    doTrustToCertificates(); 
    soapResponse = soapConnection.call(message, url);