SSL-квитирование прервано при попытке подключиться к серверу Kuzzle

#java #android #ssl #kuzzle

#java #Android #ssl #kuzzle

Вопрос:

Я использую Kuzzle с его Android SDK (3.0.10) для получения уведомлений с помощью системы pub / sub.

В Android 5 и 6, когда я пытаюсь подключиться к серверу, выполняется обратный вызов с ошибкой с сообщением: {«сообщение»: «Рукопожатие SSL прервано: ssl = 0x7f382c540280: ошибка ввода-вывода во время системного вызова, сброс соединения одноранговым узлом»}

В других версиях 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 не включен.

Поиск в Интернете я нашел несколько решений, таких как отключить 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, options, 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, 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, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
    }

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

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

    private Socket enableTLSOnSocket(Socket socket) {
        if(socket != null amp;amp; (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();
    }
  

Если кто-нибудь знает, что происходит, я был бы очень признателен. Большое спасибо!