我正在使用Java 6(SunJSSE)中的默认JSSE提供程序,
SSLContext sslCtx = SSLContext.getInstance("TLS");
我可以安全地从多个线程调用方法sslCtx.createSSLEngine()
吗?
更新1:
以这种方式调用createSSLEngine()
的代码仅在服务器端运行。基本上,线程为连接到服务器的每个客户端调用此方法。
答案 0 :(得分:2)
对when
的调用似乎是线程安全的。至少基于应用程序没有因任何与竞争条件相关的错误而失败的事实。
在尝试找到明确的答案时,我下载了OpenJDK6 b27的源代码并查看了它。当然,我假设这与Oracle JRE 6中的代码相同。
当调用SSLContext.createSSLEngine()
时,它会调用抽象方法SSLContext.createSSLEngine()
,无论它具有engineCreateSSLEngine()
类的任何实现。在这种情况下,实现是javax.net.ssl.SSLContextSpi
。 sun.security.ssl.SSLContextImpl
提供的engineCreateSSLEngine()
方法的实现只是通过调用SSLContextImpl
构造函数返回sun.security.ssl.SSLEngineImpl的新实例。
检查代码时,我找不到任何可能导致线程不安全操作的内容。
答案 1 :(得分:0)
我也同意Elliot关于OpenJDK8中SSLContext.createSSLEngine()
的线程安全性(基于分析代码和执行简单测试)。
我添加了这个答案,因为有些情况下你必须重新使用SSLContext
(如果你不喜欢包装类或不能使用同步):使用SSL加密连接到Wildfly应用程序服务器EJB时,jboss-remoting EndpointImpl
决定基于包含ConnectionKey
实例的SSLContext
打开新连接。因此,如果始终为每个EJB调用指定新的SSLContext
,则始终使用新连接。令人遗憾的是,连接被认为是“共享”的,所以它在调用后没有关闭(但由于ConnectionKey
s不同而从未重复使用)。过了一段时间,你只会得到很多:
Caused by: java.net.SocketException: No buffer space available
at sun.nio.ch.Net.socket0(Native Method) ~[?:1.8.0_91]
at sun.nio.ch.Net.socket(Net.java:411) ~[?:1.8.0_91]
at sun.nio.ch.Net.socket(Net.java:404) ~[?:1.8.0_91]
at sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:105) ~[?:1.8.0_91]
at sun.nio.ch.SelectorProviderImpl.openSocketChannel(SelectorProviderImpl.java:60) ~[?:1.8.0_91]
at java.nio.channels.SocketChannel.open(SocketChannel.java:145) ~[?:1.8.0_91]
at org.xnio.nio.WorkerThread.openTcpStreamConnection(WorkerThread.java:250) ~[xnio-nio-3.6.2.Final.jar:3.6.2.Final]
at org.xnio.XnioIoThread.internalOpenTcpStreamConnection(XnioIoThread.java:247) ~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
at org.xnio.XnioIoThread.openStreamConnection(XnioIoThread.java:226) ~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
at org.xnio.XnioWorker.openStreamConnection(XnioWorker.java:398) ~[xnio-api-3.6.2.Final.jar:3.6.2.Final]
at org.jboss.remoting3.remote.RemoteConnectionProvider.createSslConnection(RemoteConnectionProvider.java:246) ~[jboss-remoting-5.0.0.
at org.jboss.remoting3.remote.HttpUpgradeConnectionProvider.createSslConnection(HttpUpgradeConnectionProvider.java:136) ~[jboss-remot
at org.jboss.remoting3.remote.RemoteConnectionProvider.connect(RemoteConnectionProvider.java:206) ~[jboss-remoting-5.0.0.Final.jar:5.
at org.jboss.remoting3.EndpointImpl.lambda$connect$6(EndpointImpl.java:618) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_91]
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:617) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:536) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.ConnectionInfo$None.getConnection(ConnectionInfo.java:83) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.ConnectionInfo.getConnection(ConnectionInfo.java:56) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.EndpointImpl.doGetConnection(EndpointImpl.java:487) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.EndpointImpl.getConnectedIdentity(EndpointImpl.java:433) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.remoting3.UncloseableEndpoint.getConnectedIdentity(UncloseableEndpoint.java:51) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.F
at org.jboss.remoting3.Endpoint.getConnectedIdentity(Endpoint.java:122) ~[jboss-remoting-5.0.0.Final.jar:5.0.0.Final]
at org.jboss.ejb.protocol.remote.RemoteEJBReceiver.lambda$getConnection$2(RemoteEJBReceiver.java:185) ~[jboss-ejb-client-4.0.9.Final.
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_91]
at org.jboss.ejb.protocol.remote.RemoteEJBReceiver.getConnection(RemoteEJBReceiver.java:185) ~[jboss-ejb-client-4.0.9.Final.jar:4.0.9
at org.jboss.ejb.protocol.remote.RemoteEJBReceiver.processInvocation(RemoteEJBReceiver.java:128) ~[jboss-ejb-client-4.0.9.Final.jar:4
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:454) ~[jboss-ejb-client-4.0.9.Final.ja
重新使用静态SSLContext
修复此问题。