SSL /双向SSL通信问题

时间:2018-04-20 16:40:12

标签: java web-services ssl tomcat8

我们已经通过以下方式在apache Tomcat8中启用了SSL通信,

<Connector port="8743" protocol="HTTP/1.1" SSLEnabled="true" 
           maxThreads="500" scheme="https" secure="true" 
           connectionTimeout="300000"
           keystoreType="pkcs12"
           keystoreFile="D:\apps\certs\runtime\certs\testserver.pfx"
           keystorePass="test"
           truststoreFile="D:\apps\certs\runtime\caLists\truststore"
           truststorePass="test"
           truststoreType="jks"
           clientAuth="want" sslProtocol="TLS" />

这里testserver.pfx是我们的服务器证书,在truststore文件中,我们拥有入站服务的所有根证书。 我能够连接其他web服务,没有任何问题,但其他Web服务无法与我们联系。由于证书问题/ SSL握手问题,它失败了。

当我与他们核实时,他们告诉我们的应用程序需要来自入站服务的客户端证书。他们告诉我们正在使用双向SSL连接,但它应该是单向SSL。

任何人都可以帮助确定此配置是单向还是双向SSL通信。如果是双向通信,如何将其更改为单向SSL通信。

更新

我已经删除了测试环境配置,因为我想知道生产环境中发生了什么,并提供了有关当前问题的更多信息。

在此版本之前,我们使用的是tomcat 7,Java 7,我们在我们的信任库中获得了他们的证书(我在IE中访问了他们的端点地址并导出了服务器证书)。

在此版本中,我们使用tomcat 8(8.5.16.0),Java 8(1.8.0_152)并在我们的信任库中删除了他们的证书条目。我们有一个安装在不同服务器上的ESB,所有入站请求都将通过此ESB进行通信。

我们的更改后,由于SSLHandshakeException,所有入站请求都在ESB中失败:收到致命警报:certificate_unknown ..这是完整的日志跟踪。

org.apache.cxf.binding.soap.SoapFault: Problem writing SAAJ model to stream: Received fatal alert: certificate_unknown
    at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:223)[178:org.apache.cxf.cxf-rt-bindings-soap:3.1.4]
    at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:174)[178:org.apache.cxf.cxf-rt-bindings-soap:3.1.4]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.clustering.FailoverTargetSelector.performFailover(FailoverTargetSelector.java:191)[183:org.apache.cxf.cxf-rt-features-clustering:3.1.4]
    at org.apache.cxf.clustering.FailoverTargetSelector.complete(FailoverTargetSelector.java:150)[183:org.apache.cxf.cxf-rt-features-clustering:3.1.4]
    at org.esb.servicelocator.cxf.internal.LocatorTargetSelector.complete(LocatorTargetSelector.java:57)[149:locator:6.1.1]
    at org.apache.cxf.endpoint.ClientImpl.completeExchange(ClientImpl.java:536)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.processResult(ClientImpl.java:584)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:523)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.clustering.FailoverTargetSelector.performFailover(FailoverTargetSelector.java:191)[183:org.apache.cxf.cxf-rt-features-clustering:3.1.4]
    at org.apache.cxf.clustering.FailoverTargetSelector.complete(FailoverTargetSelector.java:150)[183:org.apache.cxf.cxf-rt-features-clustering:3.1.4]
    at org.esb.servicelocator.cxf.internal.LocatorTargetSelector.complete(LocatorTargetSelector.java:57)[149:locator:6.1.1]
    at org.apache.cxf.endpoint.ClientImpl.completeExchange(ClientImpl.java:536)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.processResult(ClientImpl.java:584)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:523)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:153)[162:org.apache.camel.camel-cxf:2.15.4]
    at org.apache.camel.impl.SynchronousDelegateProducer.process(SynchronousDelegateProducer.java:62)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:129)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.ChoiceProcessor.process(ChoiceProcessor.java:111)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)[161:org.apache.camel.camel-core:2.15.4]
    at org.apache.camel.component.cxf.CxfConsumer$1.asyncInvoke(CxfConsumer.java:95)[162:org.apache.camel.camel-cxf:2.15.4]
    at org.apache.camel.component.cxf.CxfConsumer$1.invoke(CxfConsumer.java:75)[162:org.apache.camel.camel-cxf:2.15.4]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)[103:org.apache.cxf.cxf-core:3.1.4]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)[:1.8.0_91]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)[:1.8.0_91]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:212)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)[11:javax.servlet-api:3.1.0]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:268)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)[76:org.eclipse.jetty.servlet:9.2.10.v20150310]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)[76:org.eclipse.jetty.servlet:9.2.10.v20150310]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:70)[94:org.ops4j.pax.web.pax-web-jetty:4.2.3]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)[74:org.eclipse.jetty.security:9.2.10.v20150310]
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:271)[94:org.ops4j.pax.web.pax-web-jetty:4.2.3]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)[76:org.eclipse.jetty.servlet:9.2.10.v20150310]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)[94:org.ops4j.pax.web.pax-web-jetty:4.2.3]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.server.Server.handle(Server.java:497)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)[75:org.eclipse.jetty.server:9.2.10.v20150310]
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)[67:org.eclipse.jetty.io:9.2.10.v20150310]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)[78:org.eclipse.jetty.util:9.2.10.v20150310]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)[78:org.eclipse.jetty.util:9.2.10.v20150310]
    at java.lang.Thread.run(Thread.java:745)[:1.8.0_91]
Caused by: com.ctc.wstx.exc.WstxIOException: Received fatal alert: certificate_unknown
    at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:255)[139:woodstox-core-asl:4.4.1]
    at org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor$SAAJOutEndingInterceptor.handleMessage(SAAJOutInterceptor.java:215)[178:org.apache.cxf.cxf-rt-bindings-soap:3.1.4]
    ... 74 more
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)[:1.8.0_91]
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)[:1.8.0_91]
    at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)[:1.8.0_91]
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125)[:1.8.0_91]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)[:1.8.0_91]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)[:1.8.0_91]
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)[:1.8.0_91]
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)[:1.8.0_91]
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)[:1.8.0_91]
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1283)[:1.8.0_91]
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1258)[:1.8.0_91]
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)[:1.8.0_91]
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:236)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1319)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1279)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:267)[113:org.apache.cxf.cxf-rt-transports-http:3.1.4]
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.io.AbstractThresholdOutputStream.unBuffer(AbstractThresholdOutputStream.java:89)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:63)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.io.CacheAndWriteOutputStream.write(CacheAndWriteOutputStream.java:80)[103:org.apache.cxf.cxf-core:3.1.4]
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:51)[103:org.apache.cxf.cxf-core:3.1.4]
    at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:100)[139:woodstox-core-asl:4.4.1]
    at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:241)[139:woodstox-core-asl:4.4.1]
    at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:253)[139:woodstox-core-asl:4.4.1]
    ... 75 more

我应该更改clientAuth = false以避免此问题吗?如果我这样做会产生任何其他问题吗?

1 个答案:

答案 0 :(得分:1)

根据Tomcat documentationclientAuth值为:

  • true - 双向
  • want - 请求双向,但允许单向
  • false - 单向(某些服务可能需要双向)

由于您指定了want,服务器将请求双向,但如果客户端未提供客户端证书,则连接仍然有效。

如果您希望某些Web服务客户端在没有证书的情况下进行连接,那么这是正确的设置。

如果客户端根本无法处理双向请求,您可以使用clientAuth="false"(默认值)在不同端口上设置单独的连接器。

<强>更新

对于正在使用的SSL协议和密码,在Java 8 TLS 1.1 and TLS 1.2 are enabled by default

如果要查看哪些密码可用以及默认情况下启用了哪些密码,请运行以下代码:

SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
TreeMap<String, Boolean> ciphers = new TreeMap<>();
for (String availableCipher : ssf.getSupportedCipherSuites())
    ciphers.put(availableCipher, Boolean.FALSE);
for (String defaultCipher : ssf.getDefaultCipherSuites())
    ciphers.put(defaultCipher, Boolean.TRUE);
System.out.println("Default\tCipher");
for (Entry<String, Boolean> cipher : ciphers.entrySet())
    System.out.println((cipher.getValue() ? '*' : ' ') + "\t" + cipher.getKey());