连接到安全的 websocket

2023-11-25

我正在尝试使用 Jetty (或任何其他库)连接到安全的 websocket。

问题是我收到“未找到受信任的证书”错误。我正在使用使用 keytool 生成的自签名证书。可以做什么?

import java.net.URI;
import java.util.concurrent.Future;

import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.eclipse.jetty.websocket.client.WebSocketClient;

public class Socket extends WebSocketAdapter{

    public static void main(String[] args) {
        String url = "wss://qa.sockets.stackexchange.com/"; //or "wss://echo.websocket.org"
        // making sure the the jvm find keystore
        String JAVASEC="C:/Program Files/Java/jdk1.8.0_25/jre/lib/security/";
        System.setProperty("javax.net.ssl.keyStore", JAVASEC+"keystore.jks");
        System.setProperty("javax.net.ssl.trustStore", JAVASEC+"cacerts.jks");
        System.setProperty("javax.net.ssl.keyStorePassword", "changeit");

        System.out.println(System.getProperty("javax.net.ssl.trustStore"));
        SslContextFactory sslContextFactory = new SslContextFactory();
        Resource keyStoreResource = Resource.newResource(Socket.class.getResource("/keystore.jks"));//generated with keytool
        sslContextFactory.setKeyStoreResource(keyStoreResource);
        sslContextFactory.setKeyStorePassword("password");
        sslContextFactory.setKeyManagerPassword("password");
        WebSocketClient client = new WebSocketClient(sslContextFactory);
        try{
            client.start();
            Socket socket = new Socket();
            Future<Session> fut = client.connect(socket,URI.create(url));
            Session session = fut.get();
            session.getRemote().sendString("Hello");
        }
        catch (Throwable t){
            t.printStackTrace(System.err);
        }
    }


    @Override
    public void onWebSocketConnect(Session sess){
        super.onWebSocketConnect(sess);
        System.out.println("Socket Connected: " + sess);
    }

    @Override
    public void onWebSocketText(String message){
        super.onWebSocketText(message);
        System.out.println("Received TEXT message: " + message);
    }

    @Override
    public void onWebSocketClose(int statusCode, String reason){
        super.onWebSocketClose(statusCode,reason);
        System.out.println("Socket Closed: [" + statusCode + "] " + reason);
    }

    @Override
    public void onWebSocketError(Throwable cause){
        super.onWebSocketError(cause);
        cause.printStackTrace(System.err);
    }
}

这是 Tyrus websocket 客户端的尝试,我没有收到 SSL 错误,但它什么也不打印:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;

import javax.websocket.ClientEndpointConfig;
import javax.websocket.CloseReason;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.MessageHandler;
import javax.websocket.Session;

import org.glassfish.grizzly.ssl.SSLContextConfigurator;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import org.glassfish.tyrus.client.ClientManager;
import org.glassfish.tyrus.container.grizzly.GrizzlyEngine;

public class ClientWebSocketEndpoint extends Endpoint {

    public static void main(String[] a) throws IOException{

        ClientManager client = ClientManager.createClient();

        //System.getProperties().put("javax.net.debug", "all");
        final SSLContextConfigurator defaultConfig = new SSLContextConfigurator();

        defaultConfig.retrieve(System.getProperties());
            // or setup SSLContextConfigurator using its API.

        SSLEngineConfigurator sslEngineConfigurator =
            new SSLEngineConfigurator(defaultConfig, true, false, false);
        client.getProperties().put(GrizzlyEngine.SSL_ENGINE_CONFIGURATOR,
            sslEngineConfigurator);
        Session session = null;
        final ClientEndpointConfig cec = ClientEndpointConfig.Builder.create().build();

        try {
            session = client.connectToServer(ClientWebSocketEndpoint.class, cec, new URI("wss://qa.sockets.stackexchange.com/"));// or "wss://echo.websocket.org"

        } catch (DeploymentException | URISyntaxException e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen())
                session.close(new CloseReason(CloseReason.CloseCodes.GOING_AWAY, "Bye"));

        }

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
    }

    @Override
    public void onOpen(Session session, EndpointConfig config) {
        session.addMessageHandler(new MessageHandler.Whole<String>() {

            @Override
            public void onMessage(String message) {
                System.out.println("Received message: "+message);
            }
        });
        try {
            session.getBasicRemote().sendText("1-questions-active");
            session.getBasicRemote().sendText("155-questions-active");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

相比之下,JS/node 中的这个简单代码可以工作

var WebSocket = require('ws')
  , ws = new WebSocket('wss://qa.sockets.stackexchange.com/');//"wss://echo.websocket.org"

ws.on('message', function(message) {
    console.log('received: %s', message);
});
ws.on('open', function() {
    ws.send('155-questions-active');
    ws.send('1-questions-active');
});

我很高兴知道 Java 中可用的 websocket 客户端


正确的方法是将您的客户端密钥库/信任库配置为信任您的特定自签名服务器证书。 stackoverflow 上有很多答案,演示了如何通过简单地适当配置密钥库和/或信任库文件内容来使用 Java 来实现此目的。 (无需代码)。

如果您只想“只是连接”,并且不关心信任、证书有效性,甚至端点身份验证(基本上构成安全连接的所有好处),那么您不需要搞乱密钥库、信任库或自定义X509TrustManagers甚至定制SSLContexts连接到该服务。这种需求在开发/测试/质量保证期间很常见,但不应在生产代码中使用。

如何使用 Jetty 9.4.35.v20201120 执行此操作只需配置SslContextFactory.Client(那属于HttpClient, which WebSocketClient正在使用)信任所有证书。

import java.net.URI;
import java.util.concurrent.Future;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.client.WebSocketClient;

@WebSocket
public class SecureClientSocket
{
    private static final Logger LOG = Log.getLogger(SecureClientSocket.class);

    public static void main(String[] args)
    {
        String url = "wss://qa.sockets.stackexchange.com/";

        SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
        // Tell sslContextFactory to trust all server certificates
        // This is suitable for test/qa environments, and internal environments,
        // but IS NOT SUITABLE FOR PRODUCTION.
        // Note: this is not actually necessary for wss://qa.sockets.stackexchange.com/
        sslContextFactory.setTrustAll(true);
        // If you do choose to comment out the above, this option will cause the
        // Java client side SSL/TLS to validate the server certificate name
        // against the URL used to connect to the server, if it doesn't match
        // then the connection is not established.
        sslContextFactory.setEndpointIdentificationAlgorithm("HTTPS");

        HttpClient httpClient = new HttpClient(sslContextFactory);
        try
        {
            httpClient.start();
            WebSocketClient client = new WebSocketClient(httpClient);
            client.start();
            SecureClientSocket socket = new SecureClientSocket();
            Future<Session> fut = client.connect(socket, URI.create(url));
            Session session = fut.get();
            session.getRemote().sendString("Hello");
            session.getRemote().sendString("155-questions-active");
        }
        catch (Throwable t)
        {
            LOG.warn(t);
        }
    }

    @OnWebSocketConnect
    public void onConnect(Session sess)
    {
        LOG.info("onConnect({})", sess);
    }

    @OnWebSocketClose
    public void onClose(int statusCode, String reason)
    {
        LOG.info("onClose({}, {})", statusCode, reason);
    }

    @OnWebSocketError
    public void onError(Throwable cause)
    {
        LOG.warn(cause);
    }

    @OnWebSocketMessage
    public void onMessage(String msg)
    {
        LOG.info("onMessage() - {}", msg);
    }
}

会有这样的结果......

2020-12-21 14:03:28.228:INFO::main: Logging initialized @173ms to org.eclipse.jetty.util.log.StdErrLog
2020-12-21 14:03:28.401:WARN:oejusS.config:main: Trusting all certificates configured for Client@4b5a5ed1[provider=null,keyStore=null,trustStore=null]
2020-12-21 14:03:28.402:WARN:oejusS.config:main: No Client EndPointIdentificationAlgorithm configured for Client@4b5a5ed1[provider=null,keyStore=null,trustStore=null]
2020-12-21 14:03:28.862:INFO:j.SecureClientSocket:HttpClient@3712b94-60: onConnect(WebSocketSession[websocket=JettyAnnotatedEventDriver[jetty.SecureClientSocket@3f38289c],behavior=CLIENT,connection=WebSocketClientConnection@7556df66::DecryptedEndPoint@11c4a450{l=/192.168.1.217:46512,r=qa.sockets.stackexchange.com/198.252.206.25:443,OPEN,fill=-,flush=-,to=66/300000},remote=WebSocketRemoteEndpoint@278a12bf[batching=true],incoming=JettyAnnotatedEventDriver[jetty.SecureClientSocket@3f38289c],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.WebSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]])
2020-12-21 14:03:30.648:INFO:j.SecureClientSocket:HttpClient@3712b94-62: onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"graphicdesign.stackexchange.com\",\"id\":138914,\"titleEncodedFancy\":\"How to achieve purple, paper background texture look?\",\"bodySummary\":\"How is the below purple background texture look achieved? I'm assuming it is a paper texture effect with different layers of light? However when I try to apply both the effect it never turns out the ...\",\"tags\":[\"texture\"],\"lastActivityDate\":1608581010,\"url\":\"https://graphicdesign.stackexchange.com/questions/138914/how-to-achieve-purple-paper-background-texture-look\",\"ownerUrl\":\"https://graphicdesign.stackexchange.com/users/155152/homan-cheung\",\"ownerDisplayName\":\"Homan Cheung\",\"apiSiteParameter\":\"graphicdesign\"}"}
2020-12-21 14:03:30.791:INFO:j.SecureClientSocket:HttpClient@3712b94-60: onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"unix.stackexchange.com\",\"id\":457386,\"titleEncodedFancy\":\"IPtables logging is not working in CentOS 7\",\"bodySummary\":\"I want to log all the traffic which comes in and out from the port X. I have followed below steps.\\r\\nEdited /etc/syslog.conf , /etc/rsyslog.conf , /etc/systemd/system/rsyslog.service.d/rsyslog.conf ...\",\"tags\":[\"centos\",\"kernel\",\"iptables\",\"logs\"],\"lastActivityDate\":1608581010,\"url\":\"https://unix.stackexchange.com/questions/457386/iptables-logging-is-not-working-in-centos-7\",\"ownerUrl\":\"https://unix.stackexchange.com/users/301499/karthikeyan-s\",\"ownerDisplayName\":\"Karthikeyan s\",\"apiSiteParameter\":\"unix\"}"}
2020-12-21 14:03:32.235:INFO:j.SecureClientSocket:HttpClient@3712b94-62: onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"math.stackexchange.com\",\"id\":812563,\"titleEncodedFancy\":\"Jacobian of exponential mapping in SO3/SE3\",\"bodySummary\":\"Following this post\\nJacobian matrix of the Rodrigues&#39; formula (exponential map)\\n\\nWhat if I really need the Jacobian of the exponential mapping function in $\\\\omega \\\\neq 0$?\\n\\nBasically, I want to ...\",\"tags\":[\"lie-groups\",\"3d\",\"rotations\",\"numerical-optimization\",\"rigid-transformation\"],\"lastActivityDate\":1608581012,\"url\":\"https://math.stackexchange.com/questions/812563/jacobian-of-exponential-mapping-in-so3-se3\",\"ownerUrl\":\"https://math.stackexchange.com/users/153816/user153816\",\"ownerDisplayName\":\"user153816\",\"apiSiteParameter\":\"math\"}"}
2020-12-21 14:03:35.343:INFO:j.SecureClientSocket:HttpClient@3712b94-60: onMessage() - {"action":"155-questions-active","data":"{\"siteBaseHostAddress\":\"raspberrypi.stackexchange.com\",\"id\":76325,\"titleEncodedFancy\":\"GCC version for compiling a loadable kernel module\",\"bodySummary\":\"I am not very familiar with Linux, so may be my question is a little bit foolish.\\n\\nI would like to compile kernel module without recompiling the kernel (USB Wi-Fi stick driver for MT7106U chip). I ...\",\"tags\":[\"kernel\",\"modules\",\"gcc\"],\"lastActivityDate\":1608581015,\"url\":\"https://raspberrypi.stackexchange.com/questions/76325/gcc-version-for-compiling-a-loadable-kernel-module\",\"ownerUrl\":\"https://raspberrypi.stackexchange.com/users/77643/cyclone125\",\"ownerDisplayName\":\"cyclone125\",\"apiSiteParameter\":\"raspberrypi\"}"}
2020-12-21 14:03:36.775:INFO:j.SecureClientSocket:JettyShutdownThread: onClose(1006, Disconnected)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

连接到安全的 websocket 的相关文章

随机推荐

  • 如何从 NIB 读取 UITableViewCell(子类)的高度?

    我在 NIB 中定义了一个 UITableViewCell 实际上是一个子类 在 NIB 中 我将框架高度设置为 183 还将 行高 设置为 183 并勾选了自定义 在我最初的问题中 这里一切都出了问题 看起来我得到了错误的高度 单元格加载
  • 使用 1 个选项取消选择“多选”中的所有选项

    我目前有以下js代码 function clearMulti option var i var select document getElementById option parentNode id for i 1 i
  • 在 Spring Data Rest 中修改 @OneToMany 实体而不使用其存储库

    在我的项目中我使用对象类型A与类型的对象具有 OneToMany 关系 orphanRemoval true cascade CascadeType ALL fetch FetchType EAGER B 我需要 SpringDataRes
  • 如何向 API 提供“回调”? [复制]

    这个问题在这里已经有答案了 我正在读一些模块文档在方法参数的解释中看到一些我不明白的东西 callback 将使用参数调用的回调函数 列表等于callbackargs result 计算完成后 callbackargs 回调函数的附加参数
  • 如何更改 R 中的分辨率(或重新网格)数据

    我有一个数据集 其中包含 lon lat 和涵盖 1961 年至 1970 年的月平均变量 例如温度或降水 该数据集的分辨率为 0 5 x 0 5 度经 纬度 覆盖整个地球 并以 我使用 R 提取数据的 NC 文件 library ncdf
  • 如何将控制台输出写入cpp中的文本文件?

    我正在尝试将控制台数据写入 cpp 中的单独文本文件中 任何人都可以帮我提供示例代码 有多种方法可以做到这一点 您可以使用以下命令从命令行重定向它programname gt out txt 或者你可以使用freopen out txt w
  • 制作不重叠的气泡图

    我目前正在尝试在 Matplotlib 中制作气泡图 其中气泡不重叠 因此将圆圈 气泡包装在图表中 大约像 我认为可能有效的方法 使用 x 1 y 1 绘制第一个数据点 通过计算给定标量值的气泡半径来随机绘制其他数据点以避免重叠 The f
  • 有关 JFreeChart 叠加的帮助

    我遇到了 JFreeChart 重叠图的问题 我正在使用 JFreeChart 1 0 13 我想要做的事情似乎在 JFreeChart 的早期版本中更容易做到 该图显示折线图和条形图 折线图绘制的 Y 轴数据范围为 0 100 范围 条形
  • 如何简化嵌套map调用?

    假设我有一些嵌套函子 例如List Option Int 并需要致电map最内在的一个 现在我正在使用嵌套maps scala gt val opts List Option Int List Some 0 Some 1 opts List
  • nodemailer 无效登录:535 身份验证失败

    我正在尝试在我的节点应用程序中使用nodemailer npm 包 通过联系页面发送电子邮件 它给我这个 535 身份验证失败错误 但我可以向您保证我的电子邮件和密码绝对正确 var express require express var
  • Rails 3 自动资产部署到 Amazon CloudFront?

    Rails 3 1 中是否有可用的 gem 或方法可以自动将资产上传到亚马逊云前端并使用这些资产而不是提供本地托管的资产 我想手动上传编译的资产然后更改 Rails 应用程序配置以使用该资产主机很容易 但是当修改资产时 需要再次手动上传到云
  • 设置 templateLocation 参数时数据流作业运行失败

    当我传递参数暂存 临时和输出 GCS 存储桶位置时 数据流作业失败并出现以下异常 Java代码 final String used Arrays copyOf args args length 1 used used length 1 pr
  • 防止在 Vim 中打开 NERDTree 或 MiniBuffExplorer 窗口内的文件

    我发现自己在 Vim 中打开了错误的窗口 有时是 NERDTree 或 MiniBuffExplorer 这真的让我很失望 我确信这种情况正在发生 因为我的光标错误地聚焦在这些窗口之一内 但是有什么我可以添加到我的 vimrc文件来防止这种
  • Postfix - 如何处理传入的电子邮件? [关闭]

    Closed 这个问题是无关 目前不接受答案 有人知道如何在 postfix 中处理虚拟邮箱的传入电子邮件吗 我正在构建 Web 应用程序 用户通过向应用程序发送电子邮件来添加新内容 每个用户使用的电子邮件地址是自定义的 例如 电子邮件受保
  • 在 Qt 中将 C++ 对象公开给 Javascript

    有什么方法可以将 C 对象 函数公开给 Qt 中 QtWebKit 浏览器内运行的 JavaScript 可以将 ActionScript 对象公开给在 Adob e AIR 中的 WebKit 浏览器内运行的 JS 代码 我正在 Qt 中
  • 在段落中放置表情符号而不影响“行高”

    如何在不影响段落内容的情况下插入表情符号line height不管表情有多大 IE 喜欢 我得到的最接近的是position absolute or vertical align text top 其中没有一个能完成这项工作 p img h
  • jQuery:获取从 中选择的文件名

    这段代码应该可以工作in IE 甚至不要在 Firefox 中测试它 但事实并非如此 我想要的是显示附件的名称 有什么帮助吗
  • Web.config 允许特定用户进行位置访问

    我有一个网络服务器 用户可以从其中下载特定于每个用户的文件 为了确保每个用户只能下载自己的文件 他们必须通过以下方式进行身份验证基本身份验证 因此 对于每个用户 服务器上都有一个 Windows 帐户 该帐户具有对用户特定文件夹的读取权限
  • HTTP 标头 Vary:* 的含义是什么

    据我所知 HTTP 标头Vary指定以逗号分隔的 HTTP 标头列表 在确定请求是缓存命中还是未命中时 缓存需要将这些标头与 URL 一起考虑 如果省略该标头 则表示仅考虑 URL 但是当标题是时会发生什么Vary RFC 2616 14
  • 连接到安全的 websocket

    我正在尝试使用 Jetty 或任何其他库 连接到安全的 websocket 问题是我收到 未找到受信任的证书 错误 我正在使用使用 keytool 生成的自签名证书 可以做什么 import java net URI import java