【问题标题】:SSL/two way SSL communication issueSSL/双向 SSL 通信问题
【发布时间】:2018-04-21 13:55:32
【问题描述】:

我们已经通过以下方式在 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,所有入站请求都在 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 以避免此问题吗?如果我这样做会产生任何其他问题吗?

【问题讨论】:

  • 如果在测试环境中使用clientAuth="want" 一切正常,这意味着客户端证书认证没有问题,您为什么要这么多谈论SSL 客户端证书?关于 Java 8,确切的版本很重要 - 请添加它 - 较新的 Java 8 版本带有无限强度加密策略(允许 aes256 和更大的 RSA 密钥大小)。
  • @Robert 我添加了 Java 版本。由于 SSL 握手问题,第一个配置失败,第二个有效。但是除了协议之外,这两者之间没有重大区别。两者都有相同的 clientAuth="want",但它在一个环境中工作而在另一个环境中失败。
  • 为什么不在协议级别比较这两种服务呢?使用ssllabs.com/ssltest 检查它们并比较启用的协议和密码。
  • 请发布实际错误信息。。没有那个,你的帖子是徒劳的。
  • '他们'错了。您完全有权申请客户证书。根据他们的配置,他们会或不会发送一个。仅仅证书请求不会导致他们最终失败,并且他们不发送也不会导致您最终失败,至少在应用程序超出 TLS 握手阶段并进入授权阶段之前。并且任何客户组织都不应该指示您不要使用客户端身份验证。这是您的服务器:您可以按照自己的意愿保护它。

标签: java web-services ssl tomcat8


【解决方案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());

【讨论】:

  • 感谢您的回复,我已经添加了一些与问题相关的更多信息
猜你喜欢
  • 1970-01-01
  • 2020-01-15
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
相关资源
最近更新 更多