Я пытаюсь запустить следующий код в android
URLConnection l_connection = null;
// Create connection
uzip=new UnZipData(mContext);
l_url = new URL(serverurl);
if ("https".equals(l_url.getProtocol())) {
System.out.println("<<<<<<<<<<<<< Before TLS >>>>>>>>>>>>");
sslcontext = SSLContext.getInstance("TLS");
System.out.println("<<<<<<<<<<<<< After TLS >>>>>>>>>>>>");
sslcontext.init(null,
new TrustManager[] { new CustomTrustManager()},
new java.security.SecureRandom());
HttpsURLConnection
.setDefaultHostnameVerifier(new CustomHostnameVerifier());
HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext
.getSocketFactory());
l_connection = (HttpsURLConnection) l_url.openConnection();
((HttpsURLConnection) l_connection).setRequestMethod("POST");
} else {
l_connection = (HttpURLConnection) l_url.openConnection();
((HttpURLConnection) l_connection).setRequestMethod("POST");
}
/*System.setProperty("http.agent", "Android_Phone");*/
l_connection.setConnectTimeout(10000);
l_connection.setRequestProperty("Content-Language", "en-US");
l_connection.setUseCaches(false);
l_connection.setDoInput(true);
l_connection.setDoOutput(true);
System.out.println("<<<<<<<<<<<<< Before Connection >>>>>>>>>>>>");
l_connection.connect();
Вкл. l_connection.connect()
Это исключение SSLhandshakeException. Иногда это работает, но в большинстве случаев дает исключение. Это происходит только в эмуляторе Android 4.0. Тестировал на Android 4.4 и 5.0, работает нормально. Что могло быть причиной этого? Пожалуйста помоги
ТРАССИРОВКИ СТЕКА
04-28 15:51:13.143: W/System.err(2915): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.143: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
04-28 15:51:13.143: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
04-28 15:51:13.143: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
04-28 15:51:13.153: W/System.err(2915): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.helpers.NetworkConnector.getConnection(NetworkConnector.java:170)
04-28 15:51:13.153: W/System.err(2915): at com.ofss.fcdb.mobile.android.rms.util.InitiateRMS$2.run(InitiateRMS.java:221)
04-28 15:51:13.153: W/System.err(2915): at java.lang.Thread.run(Thread.java:856)
04-28 15:51:13.153: W/System.err(2915): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x870c918: Failure in SSL library, usually a protocol error
04-28 15:51:13.153: W/System.err(2915): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:658 0xb7c393a1:0x00000000)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
04-28 15:51:13.153: W/System.err(2915): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
04-28 15:51:13.153: W/System.err(2915): ... 11 more
04-28 16:42:44.139: W/ResourceType(3140): No package identifier when getting value for resource number 0x00000000
android
ssl
sslhandshakeexception
android-4.0.3-ice-cream-sandwich
Бхавит С. Сенгар
источник
источник
Ответы:
Я нашел решение, проанализировав пакеты данных с помощью wirehark. Я обнаружил, что при создании безопасного соединения Android откатился к SSLv3 с TLSv1 . Это ошибка в версиях Android <4.4, и ее можно решить, удалив протокол SSLv3 из списка включенных протоколов. Я создал собственный класс socketFactory под названием NoSSLv3SocketFactory.java. Используйте это для создания фабрики сокетов.
Используйте этот класс следующим образом при подключении:
ОБНОВИТЬ :
Теперь правильным решением будет установка нового провайдера безопасности с помощью сервисов Google Play :
Это фактически дает вашему приложению доступ к более новой версии OpenSSL и Java Security Provider, которая включает поддержку TLSv1.2 в SSLEngine. После установки нового провайдера вы можете создать SSLEngine, который поддерживает SSLv3, TLSv1, TLSv1.1 и TLSv1.2 обычным способом:
Или вы можете ограничить включенные протоколы, используя
engine.setEnabledProtocols
.Не забудьте добавить следующую зависимость ( проверьте последнюю версию здесь ):
Для получения дополнительной информации перейдите по этой ссылке .
источник
Сценарий
Я получал исключения SSLHandshake на устройствах под управлением версий Android до Android 5.0. В моем случае использования я также хотел создать TrustManager, чтобы доверять моему клиентскому сертификату.
Я реализовал NoSSLv3SocketFactory и NoSSLv3Factory чтобы удалить SSLv3 из списка поддерживаемых протоколов моего клиента, но я не смог заставить ни одно из этих решений работать.
Некоторые вещи, которые я узнал:
Что сработало для меня
Разрешите
Provider
обновление безопасности Android при запуске приложения.Поставщик по умолчанию до 5.0+ не отключает SSLv3. Если у вас есть доступ к сервисам Google Play, довольно просто исправить поставщика безопасности Android из вашего приложения.
Если вы теперь создаете свой OkHttpClient или HttpURLConnection, TLSv1.1 и TLSv1.2 должны быть доступны в качестве протоколов, а SSLv3 следует удалить. Если клиент / соединение (или, точнее, SSLContext) были инициализированы перед вызовом,
ProviderInstaller.installIfNeeded(...)
его необходимо создать заново.Не забудьте добавить следующую зависимость ( последняя версия найдена здесь ):
Источники:
В стороне
Мне не нужно было явно указывать, какие алгоритмы шифрования следует использовать моему клиенту, но я нашел сообщение SO, в котором рекомендуются те, которые считались наиболее безопасными на момент написания: Какие наборы шифров включить для SSL Socket?
источник
Также вы должны знать, что вы можете принудительно использовать TLS v1.2 для устройств Android 4.0, на которых он не включен по умолчанию:
Поместите этот код в onCreate () вашего файла приложения :
источник
Раньше я также решал эту проблему с помощью специальной
SSLFactory
реализации, но, согласно документам OkHttp, решение намного проще.Мое окончательное решение с необходимыми
TLS
шифрами для устройств 4.2+ выглядит так:Обратите внимание, что набор поддерживаемых протоколов зависит от конфигурации вашего сервера.
источник
Я нашел решение здесь по этой ссылке .
Вам просто нужно поместить код ниже в свой класс приложения Android. И этого достаточно. Не нужно вносить никаких изменений в настройки дооснащения. Это спасло мне день.
Надеюсь, это поможет. Спасибо.
источник
Это решило это для меня:
android 4.1. включить tls1.1 и tls 1.2
источник
У меня тоже есть проблема с отчетом об ошибке. Мой код ниже.
Я использую Springboot в качестве серверной части и использую Android OKHttp для получения информации. Критическая ошибка, которую я сделал, заключалась в том, что я использовал .url ( "https : //10.0.2.2: 8010 / getShopInfo / aaa") в коде Android. Но мой бэкэнд не разрешен https-запрос. После того, как я использую .url (" http : //10.0.2.2: 8010 / getShopInfo / aaa") , мой код прошел хорошо. Итак, я хочу сказать, что моя ошибка не в версии эмулятора, а в протоколе запроса. После того, как я сделал то, что я сказал, я столкнулся с другой проблемой, но это другая проблема, и я прилагаю метод решения новой проблемы .
Удачи! ПАРЕНЬ!
источник
Это было воспроизводимо, только когда я использовал прокси на genymotion (<4.4).
Проверьте настройки прокси в Настройки-> Беспроводные сети-> WiFi -> (Длительное нажатие WiredSSID) -> Изменить сеть.
Выберите Показать дополнительные параметры: установите для параметров прокси значение НЕТ.
источник
Когда я получил эту ошибку, это произошло потому, что протоколы (версии TLS) и / или комплекты шифров, поддерживаемые сервером, не были включены (и, возможно, даже не поддерживаются) на устройстве. Для API 16-19 TLSv1.1 и TLSv1.2 поддерживаются, но не включены по умолчанию. После того, как я включил их для этих версий, я все еще получал ошибку, потому что эти версии не поддерживают ни один из шифров в нашем экземпляре AWS CloudFront.
Поскольку невозможно добавить шифрование в Android, нам пришлось переключить нашу версию CloudFront с TLSv1.2_2018 на TLSv1.1_2016 (которая по-прежнему поддерживает TLSv1.2; она просто не требует этого), которая имеет четыре шифра, поддерживаемых более ранние версии Android, две из которых до сих пор считаются сильными.
В этот момент ошибка исчезла, и вызовы прошли (с TLSv1.2), потому что был хотя бы один протокол и хотя бы один шифр, которые совместно использовали устройство и сервер.
Обратитесь к таблицам на этой странице, чтобы узнать, какие протоколы и шифры поддерживаются и включены в каких версиях Android.
Действительно ли Android пытался использовать SSLv3, как следует из части сообщения об ошибке «sslv3 alert handshake failure»? Я сомневаюсь в этом; Я подозреваю, что это старая паутина в библиотеке SSL, которую еще не убрали, но я не могу сказать наверняка.
Чтобы включить TLSv1.2 (и TLSv1.1), я смог использовать гораздо более простой,
SSLSocketFactory
чем те, которые видели в другом месте (например,NoSSLv3SocketFactory
). Он просто проверяет, что включенные протоколы включают все поддерживаемые протоколы и что включенные шифры включают все поддерживаемые шифры (последний не был необходим для меня, но он мог быть для других) - см.configure()
Внизу. Если вы предпочитаете использовать только самые последние протоколы, вы можете заменить ихsocket.supportedProtocols
чем-то вродеarrayOf("TLSv1.1", "TLSv1.2")
( как и для шифров):источник
Я решил проблему этим: NoSSLv3SocketFactory.java
Основной класс:
источник
Мой ответ близок к приведенным выше ответам, но вам нужно написать класс точно, ничего не меняя.
}
и использовать его с HttpsURLConnection
источник