Java 使用SSLSocketFactory绕过证书验证

Java 使用SSLSocketFactory绕过证书验证,java,ssl,ssl-certificate,jax-ws,Java,Ssl,Ssl Certificate,Jax Ws,我正在构建一个客户端应用程序,它将通过soap消息连接到第三方服务器。我使用的是运行在JBoss4.2.3上的jax ws 2.1.9和jdk 1.618 问题本身是,服务器(仅为测试目的配置)正在返回过期的证书,因此,我的应用程序引发下面的异常 13:43:26,738 ERROR [STDERR] Caused by: javax.xml.ws.WebServiceException: java.io.IOException: Could not transmit message 13:43

我正在构建一个客户端应用程序,它将通过soap消息连接到第三方服务器。我使用的是运行在JBoss4.2.3上的jax ws 2.1.9和jdk 1.618

问题本身是,服务器(仅为测试目的配置)正在返回过期的证书,因此,我的应用程序引发下面的异常

13:43:26,738 ERROR [STDERR] Caused by: javax.xml.ws.WebServiceException: java.io.IOException: Could not transmit message
13:43:26,739 ERROR [STDERR]     at org.jboss.ws.core.jaxws.client.ClientImpl.handleRemoteException(ClientImpl.java:404)
13:43:26,739 ERROR [STDERR]     at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:314)
13:43:26,739 ERROR [STDERR]     at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:172)
13:43:26,739 ERROR [STDERR]     at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:152)
13:43:26,739 ERROR [STDERR]     at $Proxy724.solicitarBaixaOperation(Unknown Source)
13:43:26,740 ERROR [STDERR]     at com.totvs.foundation.exchange.connector.ptu.implementation.v70_batch.InvoiceWriteOffConnector.process(InvoiceWriteOffConnector.java:91)
13:43:26,740 ERROR [STDERR]     ... 98 more
13:43:26,740 ERROR [STDERR] Caused by: java.io.IOException: Could not transmit message
13:43:26,740 ERROR [STDERR]     at org.jboss.ws.core.client.HTTPRemotingConnection.invoke(HTTPRemotingConnection.java:255)
13:43:26,740 ERROR [STDERR]     at org.jboss.ws.core.client.SOAPProtocolConnectionHTTP.invoke(SOAPProtocolConnectionHTTP.java:73)
13:43:26,741 ERROR [STDERR]     at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:339)
13:43:26,741 ERROR [STDERR]     at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:302)
13:43:26,741 ERROR [STDERR]     ... 102 more
13:43:26,741 ERROR [STDERR] Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker. java.security.cert.CertificateExpiredException: NotAfter: Thu Sep 11 09:35:00 GMT-03:00 2014.
13:43:26,741 ERROR [STDERR]     at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:348)
13:43:26,742 ERROR [STDERR]     at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:137)
13:43:26,742 ERROR [STDERR]     at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
13:43:26,742 ERROR [STDERR]     at org.jboss.remoting.Client.invoke(Client.java:1634)
13:43:26,742 ERROR [STDERR]     at org.jboss.remoting.Client.invoke(Client.java:548)
13:43:26,742 ERROR [STDERR]     at org.jboss.ws.core.client.HTTPRemotingConnection.invoke(HTTPRemotingConnection.java:233)
13:43:26,743 ERROR [STDERR]     ... 105 more
13:43:26,743 ERROR [STDERR] Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateExpiredException: NotAfter: Thu Sep 11 09:35:00 GMT-03:00 2014
13:43:26,743 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
13:43:26,743 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)
13:43:26,744 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
13:43:26,744 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
13:43:26,744 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035)
13:43:26,744 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124)
13:43:26,744 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
13:43:26,745 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
13:43:26,745 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
13:43:26,745 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112)
13:43:26,745 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1139)
13:43:26,745 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
13:43:26,746 ERROR [STDERR]     at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
13:43:26,746 ERROR [STDERR]     at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
13:43:26,746 ERROR [STDERR]     at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:904)
13:43:26,746 ERROR [STDERR]     at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
13:43:26,746 ERROR [STDERR]     at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:277)
13:43:26,747 ERROR [STDERR]     ... 110 more
13:43:26,747 ERROR [STDERR] Caused by: java.security.cert.CertificateExpiredException: NotAfter: Thu Sep 11 09:35:00 GMT-03:00 2014
13:43:26,747 ERROR [STDERR]     at sun.security.x509.CertificateValidity.valid(CertificateValidity.java:256)
13:43:26,747 ERROR [STDERR]     at sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:570)
13:43:26,747 ERROR [STDERR]     at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:134)
13:43:26,748 ERROR [STDERR]     at sun.security.validator.Validator.validate(Validator.java:218)
13:43:26,748 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
13:43:26,748 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
13:43:26,748 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
13:43:26,748 ERROR [STDERR]     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014)
13:43:26,749 ERROR [STDERR]     ... 122 more
因此,出于测试目的,我试图绕过这些验证。我发现了一些博客和帖子,这些都让我想到了下面的代码片段

/**
Inner class for set a blind TrustManager
**/
public class BlindTrustManager implements X509TrustManager {
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
    public void checkClientTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }
    public void checkServerTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
    }
}

/*Get the port instance of the web service interface created by JAX-WS*/
SolicitarBaixaPortType port = InvoiceWriteOffWebService.getInstance(serviceName, wsdlLocation);

/*set the socket factory*/
SSLContext ctx = SSLContext.getInstance("TLSv1");
            ctx.init(null, new TrustManager[] { new BlindTrustManager() }, null);
            SSLSocketFactory sslSocketFactory = ctx.getSocketFactory();
            ((BindingProvider) port).getRequestContext().put(BindingProviderProperties.SSL_SOCKET_FACTORY, sslSocketFactory);
((BindingProvider) port).getRequestContext().put(com.sun.xml.internal.ws.client.BindingProviderProperties.SSL_SOCKET_FACTORY, sslSocketFactory);

/*message is the Object Jax generated*/
response = port.solicitarBaixaOperation(message);
虽然我已经设置了SSLSocketFactory,但CertificateExpiredException仍在抛出。因此,它提出了以下问题:

  • 我做得对吗
  • 如何确保连接看到我的BlindTrustManager类?因为我在日志上看不到有任何提及
  • 如何确保需要传递到BindingProvider请求上下文的正确字符串可以找到我的SSLSocketFactory
  • 在JBoss中还有其他配置吗

  • 谢谢

    这是一个猜测,因为我不熟悉这个框架,但是如果jboss使用的是url.openConnection(),那么我认为您需要设置JVM范围的默认值

    javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sslSocketFactory);
    

    n、 b.这可能会有更广泛的影响,如果有效的话,也许你可以特别将此证书列入白名单。

    “出于测试目的”总是让我对上帝产生恐惧。真正的问题是为什么证书过期了?编写“出于测试目的”的代码来避免这种情况,这只是将“出于测试目的”的代码泄漏到生产环境中的一种方法,在生产环境中,这种代码将保持多年未经检查和不安全。解决问题。我同意你的观点,这并不能解决问题,但是证书已经过期,因为web服务的所有者没有在他的测试环境中修复它。正如我之前所说,这是一项第三方服务,我没有任何办法加以干预。有没有一种方法可以在没有业主干预的情况下妥善解决这个问题?