javax.net.ssl.SSLProtocolException Исключение: SSL-рукопожатие прервано: ssl=0x7fa2258640: Сбой в библиотеке SSL, обычно ошибка протокола

#java #android #mongodb #realm #mongodb-atlas

Вопрос:

Я пытаюсь использовать демонстрационное приложение для Android для подключения сервлета (как локального сервера, так и экземпляра aws), оно выдает ошибку сбоя рукопожатия. Я также пробовал использовать volley и http — клиент. Соответствующий код и результат logcat следующие. В настоящее время я использую Android версии 7.1 и мобильный телефон redmi 5A для тестирования.

 import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        execute();
    }

    void execute() {
        new Thread(new Runnable() {
            public void run() {
                try {
            URL url = new URL("https://192.168.0.7:9999/WebS/welcome/test");
            URLConnection connection = url.openConnection();

            String inputString = "hello server";
            //inputString = URLEncoder.encode(inputString, "UTF-8");

            Log.d("inputString", inputString);

            connection.setDoOutput(true);
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
            out.write(inputString);
            out.close();

            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            Toast.makeText(MainActivity.this, in.toString(), Toast.LENGTH_LONG).show();

            in.close();
        } catch (Exception e) {
            Log.e("YOUR_APP_LOG_TAG", "I got an error", e);
        }
    }
}).start();}}
 

Результат Logcat:

app_url E/YOUR_APP_LOG_TAG: Я получил ошибку javax.net.ssl.SSLHandshakeException: Не удалось выполнить рукопожатие в com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429) в com.android.okhttp.Соединение.connectTls(Соединение.java:235) на com.android.okhttp.Connection.connectSocket(Соединение.java:199) на com.android.okhttp.Подключение.подключитесь(Connection.java:172) по адресу com.android.okhttp.Connection.connectAndSetOwner(подключение.java:367) по адресу com.android.okhttp.OkHttpClient$1.Владелец подключения(OkHttpClient.java:130) по адресу com.android.okhttp.внутренний.http.HttpEngine.connect(HttpEngine.java:330) на com.android.okhttp.внутренний.http.HttpEngine.sendRequest(HttpEngine.java:247) по адресу <url>.андроид.okhttp.внутренние.ЮК.HttpURLConnectionImpl.инструкции execute(HttpURLConnectionImpl.в Java:457) на ком.андроид.okhttp.внутренние.ЮК.HttpURLConnectionImpl.функция connect(HttpURLConnectionImpl.Ява:126) на ком.андроид.okhttp.внутренние.ЮК.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.в Java:257) в ком.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218) в com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java) в com.example.cg_dte.app_url.MainActivity$1.запустите(MainActivity.java:41) в java.lang.Thread.run(Thread.java:760) Подавлено: Исключение javax.net.ssl.SSLHandshakeException: Не удалось выполнить рукопожатие … еще 15 Подавлено: Исключение javax.net.ssl.SSLHandshakeException: Не удалось выполнить рукопожатие … 15 более вызванный: класс javax.нет.протокол SSL.SSLProtocolException: SSL рукопожатие прервано: протокол SSL=0x7fa2258640: ошибка в SSL библиотеки, обычно протокол выдается сообщение Ошибка:100000f7:протокол SSL процедуры:OPENSSL_internal:WRONG_VERSION_NUMBER (внешние/в BoringSSL/src/и по протоколу SSL/tls_record.с:192 0x7f94590e7e:от 0x00000000) на ком.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Собственный метод) в com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357) … еще 14 Вызвано: javax.net.ssl.SSLProtocolException: Прервано SSL-рукопожатие: ssl=0x7fa2258640: Сбой в библиотеке SSL, обычно ошибка протокола ошибка:100000f7:Процедуры SSL:OPENSSL_internal:НЕПРАВИЛЬНЫЙ НОМЕР версии (внешний/boringssl/src/ssl/tls_record.c:192 0x7f94590e7e:0x00000000) в com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Собственный метод) в com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357) … еще 14 Вызвано: javax.net.ssl.SSLProtocolException: SSL-рукопожатие прервано: ssl=0x7fa2258640: Сбой в библиотеке SSL, обычно ошибка протокола ошибка:100000f7:Процедуры SSL:OPENSSL_internal:НЕВЕРНЫЙ НОМЕР_ВЕРСИИ (внешний/boringssl/src/ssl/tls_record.c:192 0x7f94590e7e:0x00000000) в com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Собственный метод) в com.android.org.conscrypt.OpenSSLSocketImpl.Начало рукопожатия(OpenSSLSocketImpl.java:357) … еще 14

Комментарии:

1. Попробуйте добавить параметр-Djavax.net.debug=all, чтобы получить подробную информацию о процессе подключения SSL.

Ответ №1:

 URL url = new URL("https://192.168.0.7:9999/WebS/welcome/test");
 

Этот URL-адрес также содержит спецификацию порта (порт 9999). Убедитесь, что ваш экземпляр сервера SSL (протокол HTTPS) настроен для прослушивания на этом порту, возможно, вы по ошибке подключаетесь к экземпляру сервера, не использующему SSL (протокол HTTP).

URL url = new URL("http://192.168.0.7:9999/WebS/welcome/test"); Попробуйте, например, проверить, работает ли связь с протоколом HTTP по этому адресу. Если да, то вам нужно подключиться к другому порту для HTTPS. Проще всего сначала попробовать использовать SSL-порт по умолчанию (443), т. Е. просто удалить номер порта: URL url = new URL("https://192.168.0.7/WebS/welcome/test");

Вы также можете попробовать все эти варианты URL-адреса в вашем любимом браузере, чтобы узнать, что он об этом думает (я лично использую firefox, URL-адрес с портом, указывающим на HTTP, приводил к странным ошибкам в отношении неправильной длины сертификата и т. Д…. Как только я исправил свой URL, чтобы указать на экземпляр HTTPS, firefox сообщил только о небезопасном соединении из-за используемого самозаверяющего сертификата, что было ожидаемо и понятно.

Правильный URL — адрес HTTPS без дополнительной настройки мобильного приложения, вероятно, приведет к сбою, javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. если вы используете самозаверяющий сертификат для своего локального сервера. Это другая проблема, и есть много документации, как с этим справиться (и в целом, как закреплять сертификаты, проверять доменные имена и создавать безопасное соединение).

Но WRONG_VERSION_NUMBER (external/boringssl/src/ssl/tls_record.c: предположим, что вы случайно подключаетесь к незашифрованному экземпляру HTTP вашего сервера, тогда SSL-рукопожатие полностью запутано.

Ответ №2:

У меня была та же проблема, и я смог решить ее, удалив «s» из URL-адреса.

Пожалуйста, измените URL на

 URL url = new URL("http://192.168.0.7:9999/WebS/welcome/test");
 

Комментарии:

1. Затем ваше «решение» использует небезопасное соединение с открытым текстом, которое постепенно приобретает статус персоны нон грата в современном Интернете. Приложение, созданное с помощью целевого SDK 26 (или 27 ?), по умолчанию не сможет установить такое соединение, и вам необходимо явно настроить файлы сетевых ресурсов, чтобы заставить устройство принимать небезопасное подключение к определенным доменам.

2. Это может быть самый неправильный ответ, который я когда-либо читал в StackOverflow