尝试连接到Kuzzle服务器时SSL握手中止

问题描述

我正在将Kuzzle与他的Android SDK(3.0.10)结合使用,以通过发布/订阅系统接收通知

在Android 5和6中,当我尝试连接到服务器时,将执行错误回调,并显示以下消息:{“ message”:“ SSL握手异常中止:ssl = 0x7f382c540280:系统调用期间I / O错误,连接重置同行”}

在其他版本的Android中,它运行完美。

                Options options = new Options();
                options.setPort(443);
                options.setofflineMode(Mode.AUTO);
                options.setSsl(true);
                kuzzle = new Kuzzle(kuzzleHost,options,new ResponseListener<Void>() {
                    @Override
                    public void onSuccess(Void response) {
                        initSubscriptions();
                    }

                    @Override
                    public void onError(JSONObject error) {
                        Log.e("Kuzzle","error");
                    }
                });

            } catch (Exception e) {
                Utils.caughtException(KuzzleSub.class.getSimpleName(),e);
            }

app / build.gradle依赖项

dependencies {
implementation 'io.kuzzle:sdk-android:3.0.10'
implementation 'tech.gusavila92:java-android-websocket-client:1.2.2'

调试Kuzzle和gusavila92.websocketclient.WebSocketClient类我发现在Android 5中,启用了websocket的协议是SSLv3,TLSv1,TLSv1.1,TLSv1.2。但是,在Android 7及更高版本中,未启用SSLv3。

在Internet上搜索时,我发现了多种解决方案,例如禁用SSLv3,仅启用TLSv1.2,创建新的SSLFactory。下面的代码是我尝试使用另一个SSLFactory创建扩展Kuzzle.java和SSLFactory.java

的类
public class ExtendedKuzzle extends Kuzzle {

    public ExtendedKuzzle(@NonNull String host,Options options,ResponseListener<Void> connectionCallback) throws URISyntaxException {
        super(host,connectionCallback);
    }

    public ExtendedKuzzle(@NonNull String host) throws URISyntaxException {
        super(host);
    }

    public ExtendedKuzzle(@NonNull String host,ResponseListener<Void> cb) throws URISyntaxException {
        super(host,cb);
    }

    public ExtendedKuzzle(@NonNull String host,Options options) throws URISyntaxException {
        super(host,options);
    }

    @Override
    protected WebSocketClient createSocket() throws URISyntaxException {
        WebSocketClient webSocketClient = super.createSocket();
        try {
//            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
//            sslContext.init(null,null,null);
            webSocketClient.setSSLSocketFactory(new TLSSocketFactory());
        } catch (Exception e) {
            e.printstacktrace();
        }
        return webSocketClient;
    }
}
public class TLSSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory internalSSLSocketFactory;

    public TLSSocketFactory() throws KeyManagementException,NoSuchAlgorithmException {
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null,null);
        internalSSLSocketFactory = context.getSocketFactory();
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return internalSSLSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return internalSSLSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket() throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket());
    }

    @Override
    public Socket createSocket(Socket s,String host,int port,boolean autoClose) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s,host,port,autoClose));
    }

    @Override
    public Socket createSocket(String host,int port) throws IOException,UnkNownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host,port));
    }

    @Override
    public Socket createSocket(String host,InetAddress localHost,int localPort) throws IOException,localHost,localPort));
    }

    @Override
    public Socket createSocket(InetAddress host,int port) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host,port));
    }

    @Override
    public Socket createSocket(InetAddress address,InetAddress localAddress,int localPort) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address,localAddress,localPort));
    }

    private Socket enableTLSOnSocket(Socket socket) {
        if(socket != null && (socket instanceof SSLSocket)) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
//            List<String> enabledProtocols = new ArrayList<>(Arrays.asList(((SSLSocket)socket).getEnabledProtocols()));
//            if (enabledProtocols.size() > 1) {
//                enabledProtocols.remove("SSLv3");
//                ((SSLSocket)socket).setEnabledProtocols(enabledProtocols.toArray(new String[0]));
//            }
        }
        return socket;
    }
}

我也试图设置一个“无疑问”的TrustManager,但没有成功:

    public static SSLSocketFactory createSslSocketFactory() throws Exception {
        TrustManager[] byPasstrustManagers = new TrustManager[] { new x509trustmanager() {
            public X509Certificate[] getAcceptedissuers() {
                return new X509Certificate[0];
            }
            public void checkClientTrusted(X509Certificate[] chain,String authType) {
            }
            public void checkServerTrusted(X509Certificate[] chain,String authType) {
            }
        } };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null,byPasstrustManagers,new java.security.SecureRandom());
        return sslContext.getSocketFactory();
    }

如果有人知道发生了什么,我将非常感激。非常感谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)