tyrus websocket ssl 握手失败

Posted

技术标签:

【中文标题】tyrus websocket ssl 握手失败【英文标题】:tyrus websocket ssl handshake has failed 【发布时间】:2017-02-05 11:16:32 【问题描述】:

我尽我所能使用 tyrus websocket 连接到服务器。

希望有人知道原因并告诉我解决方法或cmets。

我使用“tyrus-client websocket”

<dependency>
    <groupId>org.glassfish.tyrus.bundles</groupId>
    <artifactId>tyrus-standalone-client</artifactId>
    <version>1.9</version>
</dependency>

用户指南是这个; https://tyrus.java.net/documentation/1.9/user-guide.html#d0e1149

但它来了 SSL Handshake has failed 异常。

我在客户端和服务器上使用了相同的密钥库。 我也尝试了 setHostVerifier 方法来全部返回 true。

我也尝试了这些库的另一个版本..

但显示异常

错误

javax.websocket.DeploymentException: SSL handshake has failed
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket._connect(GrizzlyClientSocket.java:380)
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket.access$000(GrizzlyClientSocket.java:103)
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket$1.call(GrizzlyClientSocket.java:228)
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket$1.call(GrizzlyClientSocket.java:224)
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket.connect(GrizzlyClientSocket.java:242)
    at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientContainer.openClientSocket(GrizzlyClientContainer.java:95)
    at org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:626)
    at org.glassfish.tyrus.client.ClientManager$3.run(ClientManager.java:673)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:826)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
    at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:496)
    at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:312)
    at com.lge.racss.test.Application2.main(Application2.java:93)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.862 s
[INFO] Finished at: 2017-02-05T20:03:45+09:00

    at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1431)
    at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
    at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214)
    at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186)
    at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469)
    at org.glassfish.grizzly.ssl.SSLConnectionContext.wrap(SSLConnectionContext.java:339)
    at org.glassfish.grizzly.ssl.SSLUtils.handshakeWrap(SSLUtils.java:298)
    at org.glassfish.grizzly.ssl.SSLBaseFilter.doHandshakeStep(SSLBaseFilter.java:627)
    at org.glassfish.grizzly.ssl.SSLFilter.doHandshakeStep(SSLFilter.java:312)
    at org.glassfish.grizzly.ssl.SSLBaseFilter.doHandshakeStep(SSLBaseFilter.java:552)
    at org.glassfish.grizzly.ssl.SSLBaseFilter.handleRead(SSLBaseFilter.java:273)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
    at org.glassfish.grizzly.strategies.Abstractiostrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
    ... 1 more
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:304)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker$1.run(Handshaker.java:919)
    at sun.security.ssl.Handshaker$1.run(Handshaker.java:916)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1369)
    at org.glassfish.grizzly.ssl.SSLUtils.executeDelegatedTask(SSLUtils.java:247)
    at org.glassfish.grizzly.ssl.SSLBaseFilter.doHandshakeStep(SSLBaseFilter.java:638)
    ... 17 more
Caused by: java.security.cert.CertificateException: No subject alternative names present
    at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:144)
    at sun.security.util.HostnameChecker.match(HostnameChecker.java:93)
    at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
    at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1496)
    ... 25 more

客户网站

package com.lge.racss.test;

import java.io.IOException;
import java.net.URI;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.EncodeException;
import javax.websocket.WebSocketContainer;

import org.eclipse.jetty.websocket.api.WebSocketAdapter;
import org.glassfish.grizzly.ssl.SSLContextConfigurator;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import org.glassfish.tyrus.client.ClientManager;
import org.glassfish.tyrus.client.ClientProperties;

public class Application2 extends WebSocketAdapter 

    static 
        System.out.println("push");
        //disableSslVerification();
    

    private static void disableSslVerification() 
        try
        
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] new X509TrustManager() 
                public java.security.cert.X509Certificate[] getAcceptedIssuers() 
                    return null;
                
                public void checkClientTrusted(X509Certificate[] certs, String authType) 
                
                public void checkServerTrusted(X509Certificate[] certs, String authType) 
                
            
            ;

            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

            // Create all-trusting host name verifier
            HostnameVerifier allHostsValid = new HostnameVerifier() 
                public boolean verify(String hostname, SSLSession session) 
                    return true;
                
            ;

            // Install the all-trusting host verifier
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
         catch (NoSuchAlgorithmException e) 
            e.printStackTrace();
         catch (KeyManagementException e) 
            e.printStackTrace();
        
    

    public static void main(String[] args) 

        final WebSocketContainer container = ContainerProvider.getWebSocketContainer();

        String url = "wss://10.177.170.140:8443/signaling"; // or
        // "wss://echo.websocket.org"
        final ClientManager client = ClientManager.createClient();

        System.getProperties().put(SSLContextConfigurator.KEY_STORE_FILE, "/key/server");
        System.getProperties().put(SSLContextConfigurator.TRUST_STORE_FILE, "/key/server");
        System.getProperties().put(SSLContextConfigurator.KEY_STORE_PASSWORD, "123456");
        System.getProperties().put(SSLContextConfigurator.TRUST_STORE_PASSWORD, "123456");

        System.out.println("propery : " + System.getProperty(SSLContextConfigurator.KEY_STORE_FILE));

        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(ClientProperties.SSL_ENGINE_CONFIGURATOR, sslEngineConfigurator);
        System.out.println("put properties");
        try (javax.websocket.Session session = client.connectToServer(WebsocketClientEndpoint.class, URI.create(url))) 
            for (int i = 1; i <= 10; ++i) 
                try 
                    System.out.println("send");
                    session.getBasicRemote().sendObject("init");
                    Thread.sleep(1000);
                 catch (EncodeException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                 catch (InterruptedException e) 
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                
            
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
         catch (DeploymentException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        

        // Application doesn't exit if container's threads are still running
        // ( ( ClientContainer )container ).stop();
    

 

【问题讨论】:

【参考方案1】:

我认为 Tyrus 1.9 在 ssl 安全连接方面存在一些问题。 我使用 Jetty 9.4 版本解决了我的问题。 这很干净。

【讨论】:

以上是关于tyrus websocket ssl 握手失败的主要内容,如果未能解决你的问题,请参考以下文章

tyrus websocket connectToServer - 如何清理守护线程

Tyrus:静默服务器启动失败

WebSocket 服务器仅使用 ssl 从握手标头接收“G”

Tyrus 使用的每个 websocket 连接有多少个线程?

javax.websockets / Tyrus 中的线程

WebSocket握手协议