Подключение к веб-сокету с самозаверяющим сертификатом в Java - PullRequest
0 голосов
/ 02 июля 2018

Мне нужно использовать Java для подключения к серверу WebSocket, который использует самозаверяющий сертификат. Я пытаюсь использовать библиотеку Jetty и довольно новичок в Java, но мне очень трудно понять, что нужно сделать. Я могу подключиться с помощью NodeJS очень просто:

const WebSocket = require('ws');
const ws = new WebSocket('wss://192.168.100.220:9000/', ['ws-valence'], {
  rejectUnauthorized: false,
});

Тем не менее, изменение примера, который я нашел на документах Jetty , не дает мне очень далеко.

Я реализовал базовый клиент, который хорошо работает с сервером эхо-тестирования, как в приведенном выше примере. Затем я настроил свой собственный протокол и IP-адрес:

  private static void connectToBasestation() {

//    String destUri = "ws://echo.websocket.org";
    String basestationUri = "wss://192.168.100.220:9000/";
    SslContextFactory ssl = new SslContextFactory(); // ssl config
    ssl.setTrustAll(true); // trust all certificates
    WebSocketClient client = new WebSocketClient(ssl); // give ssl config to client
    BasestationSocket socket = new BasestationSocket();
    ArrayList<String> protocols = new ArrayList<String>();
    protocols.add("ws-valence");

    try
    {
        client.start();
        URI bsUri = new URI(basestationUri);
        ClientUpgradeRequest request = new ClientUpgradeRequest();
        request.setSubProtocols(protocols);
        client.connect(socket, bsUri, request);
        System.out.printf("Connecting to : %s%n", bsUri);

        // wait for closed socket connection.
        socket.awaitClose(5,TimeUnit.SECONDS);
    }
    catch (Throwable t)
    {
        t.printStackTrace();
    }
    finally
    {
        try
        {
            client.stop();
        }
        catch (Exception e)
        {
            e.printStackTrace();

        }
    }
  }

Однако я получаю UpgradeException с 0 null в качестве значений, и мой метод onConnect никогда не вызывается. Я предполагаю, что это проблема безопасности, но я не могу быть уверен, так как сервер - старая машина - что-то вроде черного ящика. Но я думаю, может быть, что-то не так с моим подходом? Кто-нибудь может дать здесь какой-нибудь совет?

Редактировать 1: Включена надежная фабрика SSL, как было предложено. Это ничего не изменило, включая трассировку стека снизу.

Редактировать 3: Существует аналогичный вопрос, перечисленный выше, но он отличается от 1) Я получаю другой код ошибки и 2) Добавление надежной фабрики SSL не решает проблему.

Редактировать 2: Вот трассировка стека, которую я получаю из моего OnError ниже:

Caused by: javax.net.ssl.SSLException: Received fatal alert: handshake_failure
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666)
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634)
    at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1800)
    at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1083)
    at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:907)
    at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:781)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.fill(SslConnection.java:681)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.process(HttpReceiverOverHTTP.java:128)
    at org.eclipse.jetty.client.http.HttpReceiverOverHTTP.receive(HttpReceiverOverHTTP.java:73)
    at org.eclipse.jetty.client.http.HttpChannelOverHTTP.receive(HttpChannelOverHTTP.java:133)
    at org.eclipse.jetty.client.http.HttpConnectionOverHTTP.onFillable(HttpConnectionOverHTTP.java:155)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
    at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:291)
    at org.eclipse.jetty.io.ssl.SslConnection$3.succeeded(SslConnection.java:151)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
    ... 3 more
org.eclipse.jetty.websocket.api.UpgradeException: 0 null
    at org.eclipse.jetty.websocket.client.WebSocketUpgradeRequest.onComplete(WebSocketUpgradeRequest.java:522)
    at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:216)
    at org.eclipse.jetty.client.ResponseNotifier.notifyComplete(ResponseNotifier.java:208)
    at org.eclipse.jetty.client.HttpReceiver.terminateResponse(HttpReceiver.java:470)
    at org.eclipse.jetty.client.HttpReceiver.abort(HttpReceiver.java:552)
    at org.eclipse.jetty.client.HttpChannel.abortResponse(HttpChannel.java:156)
    at org.eclipse.jetty.client.HttpSender.terminateRequest(HttpSender.java:381)
    at org.eclipse.jetty.client.HttpSender.abort(HttpSender.java:566)
    at org.eclipse.jetty.client.HttpSender.anyToFailure(HttpSender.java:350)
    at org.eclipse.jetty.client.HttpSender$CommitCallback.failed(HttpSender.java:717)
    at org.eclipse.jetty.client.http.HttpSenderOverHTTP$HeadersCallback.failed(HttpSenderOverHTTP.java:310)
    at org.eclipse.jetty.io.WriteFlusher$PendingState.fail(WriteFlusher.java:263)
    at org.eclipse.jetty.io.WriteFlusher.onFail(WriteFlusher.java:516)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint$FailWrite.run(SslConnection.java:1251)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:680)
    at java.lang.Thread.run(Thread.java:748)

1 Ответ

0 голосов
/ 02 июля 2018

У вас есть 2 шага.

  1. Включить SSL / TLS для клиента WebSocket
  2. Доверять всем сертификатам в конфигурации SSL / TLS

Пример:

 SslContextFactory ssl = new SslContextFactory(); // ssl config
 ssl.setTrustAll(true); // trust all certificates
 WebSocketClient client = new WebSocketClient(ssl); // give ssl config to client
...