You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为java_websocket仅配置TLSv1.3?禁用旧协议后握手报错解决

为java_websocket仅启用TLSv1.3的配置方案

你遇到的javax.net.ssl.SSLHandshakeException: Received fatal alert: protocol_version异常,本质是客户端与服务端SSL协议版本不匹配——禁用旧版协议后,java_websocket默认SSL配置未明确指定仅使用TLSv1.3,导致握手协商失败。

以下是仅启用TLSv1.3的具体配置步骤:

1. 创建仅支持TLSv1.3的SSLSocketFactory

通过自定义SSLSocketFactory,强制指定SSL协议仅为TLSv1.3:

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;

public class TLS13SocketFactoryProvider {
    public static SSLSocketFactory getTLS13OnlySocketFactory() throws NoSuchAlgorithmException {
        // 初始化TLSv1.3上下文
        SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
        sslContext.init(null, null, null); // 使用默认信任/密钥管理器,如需自定义可替换参数

        // 设置仅启用TLSv1.3协议
        SSLParameters sslParams = sslContext.getDefaultSSLParameters();
        sslParams.setProtocols(new String[]{"TLSv1.3"});

        // 包装原生SSLSocketFactory,确保所有创建的Socket都应用TLSv1.3参数
        return new SSLSocketFactory() {
            private final SSLSocketFactory delegate = sslContext.getSocketFactory();

            @Override
            public String[] getDefaultCipherSuites() {
                return delegate.getDefaultCipherSuites();
            }

            @Override
            public String[] getSupportedCipherSuites() {
                return delegate.getSupportedCipherSuites();
            }

            @Override
            public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
                Socket socket = delegate.createSocket(s, host, port, autoClose);
                ((javax.net.ssl.SSLSocket) socket).setSSLParameters(sslParams);
                return socket;
            }

            @Override
            public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
                Socket socket = delegate.createSocket(host, port);
                ((javax.net.ssl.SSLSocket) socket).setSSLParameters(sslParams);
                return socket;
            }

            @Override
            public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
                Socket socket = delegate.createSocket(host, port, localHost, localPort);
                ((javax.net.ssl.SSLSocket) socket).setSSLParameters(sslParams);
                return socket;
            }

            @Override
            public Socket createSocket(InetAddress host, int port) throws IOException {
                Socket socket = delegate.createSocket(host, port);
                ((javax.net.ssl.SSLSocket) socket).setSSLParameters(sslParams);
                return socket;
            }

            @Override
            public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
                Socket socket = delegate.createSocket(address, port, localAddress, localPort);
                ((javax.net.ssl.SSLSocket) socket).setSSLParameters(sslParams);
                return socket;
            }
        };
    }
}

2. 在WebSocketClient中应用自定义SocketFactory

初始化WebSocketClient时,将上述自定义的SSLSocketFactory传入:

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI;
import java.net.URISyntaxException;

public class CustomWebSocketClient extends WebSocketClient {

    public CustomWebSocketClient(URI serverUri) {
        super(serverUri);
        try {
            // 设置仅支持TLSv1.3的Socket
            setSocket(TLS13SocketFactoryProvider.getTLS13OnlySocketFactory().createSocket());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        System.out.println("WebSocket连接已建立");
    }

    @Override
    public void onMessage(String message) {
        System.out.println("收到消息: " + message);
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        System.out.println("连接关闭,原因: " + reason);
    }

    @Override
    public void onError(Exception ex) {
        ex.printStackTrace();
    }

    public static void main(String[] args) throws URISyntaxException {
        // 替换为你的WebSocket服务地址
        WebSocketClient client = new CustomWebSocketClient(new URI("wss://your-server-domain/path"));
        client.connect();
    }
}

关键注意事项

  • Java版本要求:Java 11及以上默认支持TLSv1.3;Java 8需升级至u261及以上版本,且需通过JVM参数-Djdk.tls.client.protocols=TLSv1.3启用。
  • 服务端兼容性:必须确保服务端已启用TLSv1.3,否则仍会出现握手失败。
  • 自定义证书:若需使用自定义信任证书,可在sslContext.init()方法中传入自定义的TrustManager数组,替换默认的信任管理器。

内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:47:03