2

Hello I've been facing a weird problem the past few days. I send out a demo of my app to a few people. however for around 75% of the people the demo didn't work, while for the other 25% it works great. (even for myself)

so I investigated and found the issue. the mayority is getting the following error when connecting to the web-socket: Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 45.116.104.89 found

Full stack trace:

[21:48:31] [pool-4-thread-1/INFO]: [com.heckvision.bingosplash.web.WebSocketManager:lambda$tryStartConnection$0:48]: Attempting to connect to WebSocket...
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:77]: WebSocket error:
[21:48:32] [WebSocketWriteThread-107/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:77]: WebSocket error:
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address 45.116.104.89 found
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1497)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:928)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at java.io.InputStream.read(InputStream.java:101)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at com.heckvision.shadowed.java_websocket.client.WebSocketClient.run(WebSocketClient.java:543)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]:   at java.lang.Thread.run(Thread.java:745)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: 

after researching I found out that this error means that the SSL certificate is not valid. this is weird since I have a valid 'lets encrypt' cert and domain. and the other 25% can connect proving the cert is valid.

the error shows I'm connecting directly to a raw IP but I'm not. im using wss://testserver.heckvision.com this domain is linked to a freshly setup test server for this demo. running nginx (for upgrading to wss) and docker (to host the web-socket)

the project is on JAVA 8. I've tried multiple versions of JAVA 8 and sorts, but nothing seems to help.

even weirder is that when I used the same class in a JAVA 21 project it works great and for 100% of the people.

I use the following java class to connect to the web-socket:

package com.heckvision.bingosplash.web;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;

import javax.net.ssl.SSLContext;
import java.net.URI;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class WebSocketManager {
    private final URI serverUri;
    private volatile WebSocketClient client; // Made volatile for thread safety
    private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    private volatile boolean shouldConnect = false; // Made volatile for thread safety
    private volatile boolean connecting = false; // Made volatile for thread safety

    private MessageListener messageListener;

    public void setMessageListener(MessageListener listener) {
        this.messageListener = listener;
    }

    public WebSocketManager(String serverUrl) {
        this.serverUri = URI.create(serverUrl);
    }

    public void setShouldConnect(boolean shouldConnect) {
        this.shouldConnect = shouldConnect;

        if (shouldConnect) {
            tryStartConnection();
        } else {
            disconnect();
        }
    }

    private void tryStartConnection() {
        if (client != null && client.getReadyState() == ReadyState.OPEN) return;
        if (connecting) return;

        connecting = true;

        executor.execute(() -> {
            try {
                System.out.println("Attempting to connect to WebSocket...");
                WebSocketClient socket = new WebSocketClient(serverUri) {
                    @Override
                    public void onOpen(ServerHandshake handshakedata) {
                        System.out.println("WebSocket connected.");
                        connecting = false; // Connection successful, clear connecting flag
                    }

                    @Override
                    public void onMessage(String message) {
                        System.out.println("Received: " + message);
                        if (messageListener != null) {
                            messageListener.onMessage(message);
                        }
                    }

                    @Override
                    public void onClose(int code, String reason, boolean remote) {
                        System.out.println("WebSocket closed: " + reason);
                        client = null;
                        connecting = false;
                        if (shouldConnect) {
                            scheduleReconnect();
                        }
                    }

                    @Override
                    public void onError(Exception ex) {
                        System.err.println("WebSocket error:");
                        ex.printStackTrace();
                        client = null;
                        connecting = false;
                        if (shouldConnect) {
                            scheduleReconnect();
                        }
                    }
                };

                SSLContext sslContext = SSLContext.getDefault();
                socket.setSocketFactory(sslContext.getSocketFactory());

                client = socket;
                socket.connect(); // Non-blocking

            } catch (Exception e) {
                System.err.println("WebSocket connect exception:");
                e.printStackTrace();
                connecting = false;
                // FIX: Only reconnect if we should still be connecting
                if (shouldConnect) {
                    scheduleReconnect();
                }
            }
        });
    }

    private void scheduleReconnect() {
        executor.schedule(this::tryStartConnection, 5, TimeUnit.SECONDS);
    }

    private void disconnect() {
        if (client != null && (client.getReadyState() == ReadyState.OPEN || client.getReadyState() == ReadyState.NOT_YET_CONNECTED)) {
            try {
                client.close();
                System.out.println("WebSocket disconnected by request.");
            } catch (Exception e) {
                System.err.println("WebSocket disconnect exception:");
                e.printStackTrace();
            }
        }
        client = null;
    }

    public void shutdown() {
        shouldConnect = false;
        disconnect();
        executor.shutdownNow();
    }
}
  • multiple versions and sorts of java - did not help
  • multiple pc and operating systems - did not help
  • adding custom ssl handshake checker - did not work and eventually came back wit the same error
  • hosting websocket on another server - did not work same error
3
  • This question is similar to: Certificate for <localhost> doesn't match any of the subject alternative names. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Aug 4 at 10:55
  • Has your Java 8 project the same audience than the Java 21 project? To me this looks like a client-side error like a TLS intercepting proxy that does something wrong causing a redirect to https://45.116.104.89. Commented Aug 4 at 16:52
  • @Robert yes it's the same audience for both projects Commented Aug 4 at 18:23

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.