SSLContext 和 SSLSocketFactory createSocket 线程安全吗? [英] Are SSLContext and SSLSocketFactory createSocket thread safe?

查看:45
本文介绍了SSLContext 和 SSLSocketFactory createSocket 线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的测试中,我能够毫无问题地使用两者,但是我找不到说明 SSLSocketFactory.createSocket() 是否线程安全的文档.是否可以在多个线程中使用相同的 SSLSocketFactory 来创建 SSL 套接字?

In my tests I was able to use both without problems, but I could not find documentation saying wheter SSLSocketFactory.createSocket() is thread safe or not. It is possible to use the same SSLSocketFactory in mutiple threads to create SSL sockets?

我的应用程序使用一个处理将纯文本套接字升级到 SSL 的类:

My application uses a class that deals with upgrading plain text sockets to SSL:

public class SSLHandler() {
    public Socket upgradeToSSL(Socket plainSocket) {
        SSLSocket sslContext = SSLContext.getInstance("TLS");
        TrustManager[] trustManager = new TrustManager[]{
            new MyOwnTrustManager()
        };

        sslContext.init(null, trustManager, null);
        SSLSocketFactory sslsocketfactory = sslContext.getSocketFactory();

        sslSocket = (SSLSocket) sslsocketfactory.createSocket(
                    remoteSocket,
                    remoteSocket.getInetAddress().getHostAddress(),
                    remoteSocket.getPort(),
                    true);

        return sslSocket;
    }
}

SSLHandler 类在多线程中使用,如下所示:

The SSLHandler class is used in mutiple threads like this:

Socket plainSocket = new Socket(host, port);
//Do some stuff in plain text...

//Lets use TLS now
SSLHandler sslHandler = new SSLHandler();
sslHandler.upgradeToSSL(Socket plainSocket);

plainSocket = upgradeToSSL(plainSocket);

因此,对于每个新线程,都会创建一个 SSLHandler.为了避免这种情况,我正在考虑使用单例模式重构 SSLHandler:

So, for each new thread a SSLHandler is created. To avoid this I'm thinking in refactoring the SSLHandler using the Singleton pattern:

public class SingletonSSLHandler() {
    private SSLSocket sslContext;
    private SSLSocketFactory sslSocketFactory;

    //GetInstance() and etc.

    private SingletonSSLHandler() {
        sslContext = SSLContext.getInstance("TLS");
        TrustManager[] trustManager = new TrustManager[]{
            new MyOwnTrustManager()
        };

        sslContext.init(null, trustManager, null);
        sslSocketFactory = sslContext.getSocketFactory();
    }

    public static Socket upgradeToSSL(Socket plainSocket) {

        sslSocket = (SSLSocket) sslsocketfactory.createSocket(
                    remoteSocket,
                    remoteSocket.getInetAddress().getHostAddress(),
                    remoteSocket.getPort(),
                    true);

        return sslSocket;
    }
}

推荐答案

这个问题不是那么容易回答的.原因是有实现,还有合约层面.

The question can't be answered so easily. The reason is that there is the implementation, but also the contract level.

实施

SSLServerSocketFactory 类是抽象的并且具有插件扩展机制.因此,从理论上讲,您无法确定自己采用的是哪种实现方式.

The SSLServerSocketFactory class is abstract and has a plugin extension mechanism. So you can't be sure what implementation you're having from the theoretic standpoint.

默认实现只是一个虚拟实现,由 JVM 选择的提供者的实现实例进行交换:

The default implementation is just a dummy and gets exchanged by an implementation instance of the provider that is being chosen by the JVM:

//
// The default factory does NOTHING.
//
class DefaultSSLServerSocketFactory extends SSLServerSocketFactory {
...
}

抽象类中有一些同步的迹象.要回答 JDK 中的实现,需要针对每个操作系统(Windows、Linux、Mac OS)上的每个 JDK 版本分析该问题.

There are some signs of synchronization in the abstract class. To give an answer to the implementation in the JDK, the question would need to be analyzed for every JDK version on each operating system (Windows, Linux, Mac OS).

当您进入下一部分的合同级别时,关键部分(同步)的存在没有任何意义.从我的角度来看,合同级别是本次讨论的重点.

The existance of cricital sections (synchronized) mean nothing when you come to the contract level in the next section. The contract level is what counts in this discussion from my perspective.

合同

事实上,如果没有 API 文档保证/承诺它是线程安全的.所以,理论上不是.您不能依赖没有 API 合同的任何内容.请阅读 此参考资料给 Josh Blochs '黄金法则 70:记录线程安全性,详细讨论关于依赖线程安全性的假设.

In fact, if there's no API documentation assuring/promising it's thread-safe. So, in theory it is not. You can't rely on anything that you don't have an API contract for. Please read this reference to Josh Blochs 'golden rule 70: Document thread safety' for a very detailed discussion on assumptions about relying on thread-safety.

我可以使用上面提到的扩展机制编写一个非线程安全的 SSLServerSocketFactory 实现.缺乏线程安全不会是一个错误,因为它不是每个接口合同的强制性要求.

I could write a non-thread-safe SSLServerSocketFactory implementation using the extension mechanism mentioned above. The lack of thread-safety wouldn't be a bug because it's not mandatory per interface contract.

总结

总而言之,API 不保证所有实现都是线程安全的.所以没有办法说会有一个(未来的)实现不是线程安全的.

To summarize, the API doesn't assure that all implementations are thread-safe. So there's no way to say that there will be a (future) implementation not thread-safe.

这篇关于SSLContext 和 SSLSocketFactory createSocket 线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆