Java Secure Websocket - 从 TLS 证书文件加载 SSL 上下文并连接到 WSS URI

Posted

技术标签:

【中文标题】Java Secure Websocket - 从 TLS 证书文件加载 SSL 上下文并连接到 WSS URI【英文标题】:Java Secure Websocket - Load SSL context from TLS cert file and connect to WSS URI 【发布时间】:2021-05-28 23:03:12 【问题描述】:

我正在寻找一种方法来加载如下所示的 TLS 证书文件 (ssl_cert_auth_params):

-----BEGIN CERTIFICATE-----
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
****************************************************************
************************
-----END CERTIFICATE-----

在 Java WSS(安全 WebSocket)客户端中。

我可以用这个在 python 中轻松设置ssl_context

import ssl
import pathlib

ssl_context   = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
localhost_pem = pathlib.Path(__file__).resolve().parent / "../../folder/ssl_cert_auth_params"
ssl_context.load_verify_locations(localhost_pem)

然后用这个连接到 WSS uri:

import asyncio
import websockets

async def connect_to_uri(uri, ssl_context):
    ws = await websockets.connect(uri, ssl=ssl_context, ping_interval=3)
    return (ws)

loop = asyncio.get_event_loop()
ws = loop.run_until_complete(connect_to_uri(uri, ssl_context))

但我找不到一个简单的方法来使用 java wss 客户端库

【问题讨论】:

您打算使用哪个 java wss 客户端库? 目前可以轻松实现此目的,当我有更多选择时,我会选择,很乐意接受建议 【参考方案1】:

我不是 websocket 专家,但这里有一个 sn-p,它应该在 java 中使用 WebSockets for Jetty 为您解决问题:

我使用了以下库:

<dependency>
   <groupId>org.eclipse.jetty.websocket</groupId>
   <artifactId>websocket-client</artifactId>
   <version>9.4.41.v20210516</version>
</dependency>
<dependency>
   <groupId>io.github.hakky54</groupId>
   <artifactId>sslcontext-kickstart-for-jetty</artifactId>
   <version>6.6.1</version>
</dependency>

还有 Java 代码:

import nl.altindag.ssl.SSLFactory;
import nl.altindag.ssl.util.CertificateUtils;
import nl.altindag.ssl.util.JettySslUtils;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.eclipse.jetty.websocket.client.WebSocketClient;

import java.net.URI;
import java.nio.file.Paths;

public class WebSocketExample 

    public static void main(String[] args) throws Exception 
        var sslFactory = SSLFactory.builder()
                .withTrustMaterial(CertificateUtils.loadCertificate(Paths.get("/path/to/certificate.pem")))
                .build();

        var sslContextFactory = JettySslUtils.forClient(sslFactory);
        var httpClient = new HttpClient(sslContextFactory);
        var webSocketClient = new WebSocketClient(httpClient);
        webSocketClient.start();

        var session = webSocketClient.connect(new MyWebSocketListener(), new URI("ws://echo.websocket.org")).get();
        session.getRemote().sendString("Hello there!");
    

    private static class MyWebSocketListener implements WebSocketListener 

        @Override
        public void onWebSocketBinary(byte[] bytes, int i, int i1) 
            System.out.println();
        

        @Override
        public void onWebSocketText(String response) 
            System.out.println(response);
        

        @Override
        public void onWebSocketClose(int i, String s) 
            System.out.println("closed");
        

        @Override
        public void onWebSocketConnect(Session session) 
            System.out.println("connected");
        

        @Override
        public void onWebSocketError(Throwable throwable) 
            System.out.println("got error");
        
    


Jetty SslContextFactory 没有直接读取和使用 pem 文件的函数。因此,您最终会添加逻辑来读取 pem 文件并将其映射到 KeyStore 对象,然后将其提供给 TrustManager,然后从中创建 SSLContext。因此,我建议我自己的库来隐藏冗长。我希望你喜欢它:)

【讨论】:

不错!通常我也可以使用“wss://”端点 URI,对吗?一旦我可以在接下来的几周内正确测试我的终点,如果没有提供其他更好的答案,我会回来接受这个。谢谢! 是的,我尝试了指向 URI 的示例 wss 链接并且它有效。但是我无法测试 SSL 部分,因为我没有安全的 wss 服务器。所以我很想听听你的结果 @madx 任何来自你的更新,你能用 ssl 试试吗?

以上是关于Java Secure Websocket - 从 TLS 证书文件加载 SSL 上下文并连接到 WSS URI的主要内容,如果未能解决你的问题,请参考以下文章

用于 TLS 上的 WebSocket Secure 的 WCF ServiceHost 配置

Unity 如何连接基于 Node.js 的 Secure WebSocket?

WSS over Secure SSL 连接仅在 FireFox 上失败,错误 1006

如何从javascript客户端onmessage函数发送/读取java ByteBuffer(websocket)

c++ websocket 客户端

Java实现WebSocket