是否可以将普通套接字更改为SSLSocket?

sod*_*ish 10 java ssl

有一个普通的socket服务器监听端口12345;

ServerSocket s = new ServerSocket(12345);
Run Code Online (Sandbox Code Playgroud)

我想知道的是:有可能:

  1. 如果客户端发送http请求,服务器直接处理请求,
  2. 如果客户端发送https请求,服务器将客户端套接字更改为SSLSocket?

谢谢

Bru*_*uno 20

是否可以将普通套接字更改为SSLSocket?

是的.在服务器端,以下工作:

ServerSocketFactory ssf = ServerSocketFactory.getDefault();
ServerSocket serverSocket = ssf.createServerSocket(12345);

// I've initialised an sslContext with a keystore, as you normally would.
Socket socket = serverSocket.accept();
SSLSocketFactory sslSf = sslContext.getSocketFactory();
// The host name doesn't really matter, since we're turning it into a server socket
// (No need to match the host name to the certificate on this side).
SSLSocket sslSocket = (SSLSocket) sslSf.createSocket(socket, null,
    socket.getPort(), false);
sslSocket.setUseClientMode(false);

// Use the sslSocket InputStream/OutputStream as usual.
Run Code Online (Sandbox Code Playgroud)

SSLSocketFactory.createSocket(Socket, ...)默认情况下会将现有Socket转换为客户端模式SSLSocket.由于握手仅在您开始使用I/O流进行读/写时开始,因此仍然需要使用更改模式setUseClientMode(false).

关于其余问题:

我想知道的是:有可能:

  • 如果客户端发送http请求,服务器直接处理请求,
  • 如果客户端发送https请求,服务器将客户端套接字更改为SSLSocket?

再次,是的,这是可能的.它有时被称为" 端口统一 ",它在GrizzlyGlassfish中实现.

它的工作原理是HTTP和TLS(HTTPS工作)都是预期客户端首先进行通信的协议.因此,服务器可以检测客户端最初发送的是TLS ClientHello消息(在这种情况下它应该尝试继续进行TLS握手)还是普通的HTTP请求(例如GET / HTTP/1.1......).

我怀疑端口统一是"更容易"使用SSLEngine,否则,在普通套接字上实现预读可能很难,你仍然可以通过它转换SSLSocketFactory.createSocket(Socket, ...).

但请注意,这仍然很不寻常.