Ssl 如何将密钥库与SAAJ SOAP调用关联

Ssl 如何将密钥库与SAAJ SOAP调用关联,ssl,soap,Ssl,Soap,我需要使用特定的SSL密钥库(.pfx或.jks)进行HTTPs调用。我正在使用SAAJ实现进行SOAP调用 以下是我要遵循的步骤。 1.设置系统属性以读取密钥库 System.setProperty("javax.net.ssl.trustStore",path to cacerts); System.setProperty("javax.net.ssl.trustStorePassword",password); System.setProperty("javax.net.ssl.keySt

我需要使用特定的SSL密钥库(.pfx或.jks)进行HTTPs调用。我正在使用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
    

    基本上,您需要将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);
    }    
    
    然后在connection.call()方法之前调用doTrustToCertificates()方法,如下所示:

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

    基本上,您需要将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);
    }    
    
    然后在connection.call()方法之前调用doTrustToCertificates()方法,如下所示:

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