java - SSL/双向 SSL 通信问题

标签 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 是我们的服务器证书,在信任库文件中我们有入站服务的所有根证书。 我能够毫无问题地连接其他网络服务,但其他网络服务无法与我们连接。由于证书问题/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:收到致命警报:certificate_unknown..这是完整的日志跟踪,ESB 中的所有入站请求都失败了。

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 以避免这个问题吗?如果我这样做会产生任何其他问题吗?

最佳答案

根据 Tomcat documentation , clientAuth 值为:

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

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

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

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


更新

关于在 Java 8 中使用的 SSL 协议(protocol)和密码 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());

关于java - SSL/双向 SSL 通信问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49946198/

相关文章:

c# - Microsoft Unity 容器的性能

node.js - NGINX中是否有类似Express.js "trust proxy"的配置?

java - 为什么调用 System.gc() 是不好的做法?

java - 组织 JPanel 和布局

Maven 中的 Javafx TableView : Incompatible types

javascript - 如何防止 angular.js $http 对象发送 X-Requested-With header ?

java - 从 URL 中检索编码值

authentication - SSL 的优势值得你费心费力吗?

php - 执行 FQL 时出现 SSL 证书问题

java - 如何修复 org.hibernate.hql.internal.ast.QuerySyntaxException : unexpected token: u