Kwert-soft.ru

IT Софт для ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Javax net ssl sslhandshakeexception handshake failed

Как решить javax.сеть.ssl.Ошибка SSLHandshakeException?

я подключился к VPN для настройки API инвентаризации, чтобы получить список продуктов, и он отлично работает. Как только я получаю результат от веб-сервиса, я привязываюсь к UI. А также я интегрировал PayPal с моим приложением для экспресс-проверки, когда я делаю вызов для оплаты, я сталкиваюсь с этой ошибкой. Я использую сервлет для внутреннего процесса. Может кто-нибудь сказать как исправить эту проблему?

6 ответов

сначала нужно получить сертификат от сервера, к которому вы пытаетесь подключиться. Это можно сделать различными способами, например, связаться с администратором сервера и попросить его,использование openssl для его загрузки, или, поскольку это, по-видимому, HTTP-сервер, подключение к нему с любым браузером, просмотр информации о безопасности страницы и сохранение копии сертификата. (Google должен быть в состоянии сказать вам точно, что делать для вашего конкретного браузера.)

теперь чтобы сертификат был сохранен в файле, его необходимо добавить в хранилище доверия JVM. At $JAVA_HOME/jre/lib/security/ для JREs или $JAVA_HOME/lib/security для JDKs есть файл с именем cacerts , который поставляется с Java и содержит публичные сертификаты известных сертификационных органов. Чтобы импортировать новый сертификат, запустите keytool как пользователь, имеющий разрешение на запись в cacerts:

он, скорее всего, попросит у вас пароль. Пароль по умолчанию, поставляемый с java, — changeit . Почти никто. изменить его. После выполнения этих относительно простых шагов вы будете общаться безопасно и с уверенностью, что вы разговариваете с правильным сервером и только с правильным сервером (если они не потеряют свой закрытый ключ).

сейчас я решил эту проблему таким образом,

конечно, это решение должно использоваться только в сценариях, где невозможно установить необходимые сертификаты с помощью keytool например, локальное тестирование с временными сертификатами.

всякий раз, когда мы пытаемся подключиться к URL-адресу,

если сервер на другом сайте работает по протоколу https и требует, чтобы мы общались через информацию, предоставленную в сертификате, то у нас есть следующий вариант:

1) попросите сертификат (загрузите сертификат), импортируйте этот сертификат в trustore. Использование Java trustore по умолчанию можно найти в Javajdk1.6.0_29jrelibsecuritycacerts, то при повторной попытке подключения к URL-соединению будет принято.

2) в обычных бизнес-случаях мы можем подключаться к внутренним URL-адресам в организациях, и мы знаем, что они верны. В таких случаях вы уверены, что это правильный URL-адрес, в таких случаях выше может использоваться код, который не будет уполномочен хранить сертификат для подключения к определенному URL-адресу.

для точки № 2 мы должны выполнить следующие шаги:

1) напишите ниже метод, который устанавливает HostnameVerifier для HttpsURLConnection, который возвращает true для всех случаев означает, что мы доверяем trustStore.

2) Напишите ниже метод, который вызывает doTrustToCertificates перед попыткой подключения к URL

этот вызов вернет код ответа = 200 означает, что соединение успешно.

для получения более подробной информации и примера примера вы можете обратиться к URL-адресом.

Я считаю, что вы пытаетесь подключиться к чему-то с помощью SSL, но что-то предоставляет сертификат, который не проверяется корневыми центрами сертификации, такими как verisign.. По сути, по умолчанию безопасные соединения могут быть установлены только в том случае, если лицо, пытающееся подключиться, знает ключи контрагентов или какой-либо другой verndor, такой как verisign, может вмешаться и сказать, что предоставляемый открытый ключ действительно прав..

доверие всей ОС несколько сертификации если вы понимаете, что я имею в виду, органы власти и мелкие эмитенты сертификатов должны быть сертифицированы одним из крупных сертифицирующих органов, образующих цепочку сертифицирующих органов.

в любом случае, возвращаясь к делу.. У меня была аналогичная проблема при программировании Java-апплета и java-сервера ( надеюсь, когда-нибудь я напишу полный блог о том, как я получил всю безопасность для работы 🙂 )

по сути, мне нужно было извлечь открытые ключи с сервера и сохранить их в хранилище ключей внутри моего апплета и при подключении к серверу я использовал это хранилище ключей для создания фабрики доверия и эту фабрику доверия для создания ssl-соединения. Существуют процедуры alterante, такие как добавление ключа к доверенному хосту JVM и изменение хранилища доверия по умолчанию при запуске..

Я сделал это около двух месяцев назад и сейчас у меня нет исходного кода.. используйте google, и вы сможете решить эту проблему. Если ты не можешь ответить мне, и я могу предоставить тебе релевантный исходный код проекта .. Не знаю, решает ли это вашу проблему, так как вы не предоставили код, который вызывает эти исключения. Кроме того, я работал с апплетами, думал, что не могу понять, почему он не будет работать на Серверлетах.

P. S Я не могу получить исходный код до выходных, так как внешний SSH отключен в моем офисе : (

Как решить javax. net. ssl. SSLHandshakeException ошибку?

Я подключился к VPN, чтобы настроить инвентаризационный API, чтобы получить список продуктов, и он работает нормально. Как только я получаю результат от веб-сервиса и привязываюсь к UI. А также я интегрировал PayPal с моим приложением для экспресс-проверки, когда я делаю звонок для оплаты, я сталкиваюсь с этой ошибкой. Я использую сервлет для внутреннего процесса. Может ли кто-нибудь сказать, как исправить эту проблему?

6 ответов:

Сначала вам нужно получить открытый сертификат от сервера, к которому вы пытаетесь подключиться. Это можно сделать различными способами, например, связаться с администратором сервера и запросить его, с помощью openssl загрузить его, или, поскольку это, по-видимому, HTTP-сервер, подключиться к нему с помощью любого браузера, просмотреть информацию о безопасности страницы и сохранить копию сертификата. (Google должен быть в состоянии точно сказать вам, что делать для вашего конкретного браузера.)

Теперь, когда у вас есть сертификат, сохраненный в файле, необходимо добавить в хранилище доверия вашего JVM. В $JAVA_HOME/jre/lib/security/ для JREs или $JAVA_HOME/lib/security для JDKs есть файл с именем cacerts , который поставляется с Java и содержит открытые сертификаты известных сертификационных органов. Чтобы импортировать новый сертификат, запустите keytool от имени пользователя, имеющего разрешение на запись в cacerts:

Читать еще:  Javascript работа с базой данных

Скорее всего, он запросит у вас пароль. Пароль по умолчанию, поставляемый с java, — changeit . Его почти никто не меняет. После того, как вы выполните их относительно простые шаги, вы будете общаться безопасно и с уверенностью, что вы говорите с правильным сервером и только с правильным сервером (до тех пор, пока они не потеряют свой закрытый ключ).

Теперь я решил эту проблему таким образом,

Конечно, это решение должно использоваться только в сценариях, где невозможно установить требуемые сертификаты, используя keytool , например, локальное тестирование с временными сертификатами.

Всякий раз, когда мы пытаемся подключиться к URL,

Если сервер на другом сайте работает по протоколу https и требует, чтобы мы общались через информацию, предоставленную в сертификате, то у нас есть следующий вариант:

1) запросите сертификат (загрузите сертификат), импортируйте этот сертификат в trustore. Trustore по умолчанию Java использует можно найти в в Javajdk1.6.0_29среда jrelib вбезопасностьcacerts в, то если мы будем пытаться подключиться к URL-адрес подключения будет принято.

2) в обычных бизнес-случаях мы можем подключаться к внутренним URL-адресам в организациях, и мы знаем, что они верны. В таких случаях вы уверены, что это правильный URL, в таких случаях выше, код может быть использован, который не будет предписывать хранить сертификат для подключения к конкретному URL.

Для пункта № 2 мы должны выполнить следующие шаги:

1) напишите ниже метод, который устанавливает HostnameVerifier для HttpsURLConnection, который возвращает true для всех случаев, означающих, что мы доверяем trustStore.

2) Напишите ниже метод, который вызывает doTrustToCertificates перед попыткой подключиться к URL

Этот вызов вернет код ответа = 200 означает, что соединение успешно.

Для получения более подробной информации и примера вы можете обратиться к URL .

Я полагаю, что вы пытаетесь подключиться к чему-то с помощью SSL, но это что-то предоставляет сертификат, который не проверяется корневыми центрами сертификации, такими как verisign.. По сути, по умолчанию безопасные соединения могут быть установлены только в том случае, если лицо, пытающееся подключиться, знает ключи контрагентов или какой-либо другой верндор, такой как verisign, может вмешаться и сказать, что предоставляемый открытый ключ действительно правильный..

Все ОС доверяют горстке сертификационных центров и более мелкие эмитенты сертификатов должны быть сертифицированы одним из крупных сертифицирующих компаний, создающих цепочку сертифицирующих компаний, если вы понимаете, что я имею в виду.

В любом случае возвращаясь к сути.. У меня была похожая проблема при программировании Java-апплета и java-сервера ( надеюсь, когда-нибудь я напишу полный блог о том, как я получил всю безопасность для работы:))

По сути, мне нужно было извлечь открытые ключи из сервера и сохранить их в хранилище ключей внутри моего апплета, а когда Я подключился к серверу, который использовал это хранилище ключей для создания фабрики доверия, а эту фабрику доверия-для создания ssl-соединения. Существуют также процедуры alterante, такие как добавление ключа к доверенному хосту JVM и изменение хранилища доверия по умолчанию при запуске..

Я сделал это около двух месяцев назад, и сейчас у меня нет исходного кода.. используйте google, и вы сможете решить эту проблему. Если вы не можете отправить мне ответное сообщение, и я могу предоставить вам соответствующий исходный код для проект.. Не знаю, решит ли это вашу проблему, так как вы не предоставили код, который вызывает эти исключения. Кроме того, я работал с апплетами, думал, что не могу понять, почему это не работает на серверах.

P. S Я не могу получить исходный код до выходных, так как внешний SSH отключен в моем офисе : (

SSLHandshakeException: сообщение о нарушении не выполнено на Andro >

Я работаю над приложением, для которого (властные) пользователи должны настроить свой собственный сервер (например, nginx) для запуска бэкэнд-приложения. Соответствующий домен должен быть настроен в приложении, чтобы он мог подключаться. Я тестировал в первую очередь на своем собственном телефоне (sony z3c) и начал развиваться для 5.1. Позже я получил обновление для 6.0, но все еще поддерживал рабочий 5.1 внутри эмулятора. Не так давно я начал работать над AVD с изображением для 7.0, и, к моему удивлению, он не будет подключаться к моему серверу, сообщая мне, что ssl handshake не удалось. Моя конфигурация nginx довольно строгая, но она работает как для 5.1, так и для 6.0, поэтому ….

  • Я использую v24 для поддержки libs, т.е. my compileSdkVersion равно 24.
  • Я использую Volley v1.0.0 .
  • Я пробовал TLSSocketFactory , но ничего не меняет. Похоже, что это используется в большинстве случаев для предотвращения использования SSL3 для старых версий SDK.
  • Я попытался увеличить тайм-аут , но ничего не изменил.
  • Я попытался напрямую использовать HttpURLConnection, но он ничего не меняет, кроме трассировки стека (без ссылок на волейбол, но идентичных в противном случае).

Без TLSSocketFactory запрос выполняется с помощью пустой очереди запросов, Volley.newRequestQueue(context) с помощью Volley.newRequestQueue(context) .

Это то, что я вижу в андроид-студии:

Поскольку он говорит SSLV3_ALERT_HANDSHAKE_FAILURE я могу только предположить, что по какой-то причине пытается подключиться с использованием SSLv3 и терпит неудачу, но это не имеет никакого смысла для меня вообще. Это может быть проблема шифрования, но как я могу сказать, что она пытается использовать? Я бы предпочел не включать шифры на сервере, сделать попытку подключения и повторить.

Мой сайт nginx использует сертификат шифрования let и имеет следующую конфигурацию:

Чтобы проверить эти шифры, у меня есть скрипт, и он подтверждает эти шифры (запускайте хриплый vps за пределами сети сервера):

Читать еще:  Minfotextview settext в java что это

Я могу открыть сервер-url в браузере эмулятора и получить идеальный ответ json, поэтому я знаю, что сама система способна.

Итак, вопрос в том, почему я не могу подключиться к Android 7?

Обновление :

Я просмотрел захваченный пакет, используя tcpdump и wirehark, а активированные шифры находятся в ClientHello, так что это не должно быть проблемой.

Как вы видите, 0xc02f и 0xc030 совпадают, но в следующем пакете TLSv1.2 говорится: Alert (21), Handshake Failure (40) подтверждения Alert (21), Handshake Failure (40) .

Обновление 2 :

Это кривые от Android 5.1 в ClientHello:

В ServerHello возвращается secp384r1 (0x0018) .

И это от Android 7:

Результатом является отказ от подтверждения.

Изменение конфигурации nginx путем удаления secp384r1 или замены его по умолчанию (prime256v1) позволяет ему работать. Поэтому, я думаю, остается вопрос: могу ли я добавить эллиптические кривые?

Захваченные данные одинаковы при использовании эмулятора, как при использовании устройства Android 7.0 (General Mobile 4G).

Обновление 3 :

Небольшое обновление, но стоит упомянуть: я получил его для работы в эмуляторе с помощью Android 7.1.1 (!). Он показывает следующие данные (опять же, с помощью tcpdump и просмотра с помощью wirehark):

Он показывает те же 18 Cipher Suites.

Это известная регрессия в Android 7.0, подтвержденная Google и исправленная когда-то до выхода Android 7.1.1. Вот отчет об ошибке: https://code.google.com/p/andro >

Чтобы быть ясным, ошибка здесь в том, что 7.0 поддерживает только одну эллиптическую кривую: prime256v1 aka secp256r1 aka NIST P-256, как указывает Корнелис в вопросе. Поэтому, если ваши пользователи сталкиваются с этой проблемой, это временные решения, доступные вам (игнорируя тот факт, что ваши пользователи в идеале должны просто перейти на Android 7.1.1):

Настройте сервер для использования эллиптической кривой prime256v1 . Например, в Nginx 1.10 вы делаете это, устанавливая ssl_ecdh_curve prime256v1; ,

Если это не сработает, используйте устаревшие комплекты шифрования, которые не полагаются на криптографию с эллиптической кривой (например, DHE-RSA-AES256-GCM-SHA384 ) (убедитесь, что вы понимаете, что вы здесь делаете с точки зрения безопасности данных )

ПРИМЕЧАНИЕ. Я не являюсь экспертом в криптографии с кривыми эллиптической кривой, не забудьте провести собственное исследование влияния безопасности на мои предложения. Вот некоторые другие ссылки, на которые я ссылался при написании этого ответа:

У меня возникла проблема с самоподписанным сертификатом, и проблема была в шифре, который не был принят Android 7.0

Я запустил: openssl s_client -showcerts -connect :

В результате я обнаружил:

Я искал эквивалент Android для Cipher и добавил его в свой Retrofit Restadapter:

Отсюда принималось каждое соединение с правильным установлением сертификата или правильным сертификатом, но с «неправильным» шифром в соответствии с Android 7.0.

Здесь вы работаете решением для Volley:

Перед созданием очереди в одноэлементных кодах:

И здесь SSLSocketFactoryExtended:

В этих кодах я просто добавляю все шифры, которые поддерживаются устройством, для меня это работает), может быть, поможет кому-то) Cheers)

Ps нет необходимости добавлять параметр конфигурации сети безопасности в манифест.

По умолчанию защищенные соединения (с использованием протоколов TLS и HTTPS) из всех приложений доверяют предварительно установленным системным ЦС и приложениям, ориентированным на Android 6.0 (API-уровень 23) и ниже, также доверяют добавленному пользователем хранилищу CA по умолчанию.

Это означает, что на Android Nougat (7.0) игра для ЦС полностью изменилась. Если у вас есть ключ сертификата, вы можете добавить файл конфигурации сетевой безопасности (если у вас есть сертификат), как описано здесь: https://developer.android.com/training/articles/security-config.html

Или вы можете включить набор шифров, который требуется вашему серверу, но не включен по умолчанию на Android N. Например, вот два шифра, которые мне нужно было добавить в свое приложение, разговаривая со старым сервером Windows CE:

Тоже самое. Мой сервер Nginx использует настройку sll_ecdh_curve prime384v1. К сожалению, сторонний парень не разрешил мне настраивать сервер Nginx, следуя инструкциям Вики Чиджвани из-за политики конфиденциальности клиента. Я попытался использовать Долину и последнюю версию библиотеки OkHttp, но это не помогло. Чтобы обойти эту ошибку, мне пришлось использовать WebView для связи с API-сервисом на устройствах Adroid 7.0. Вот мой класс адаптера. Я надеюсь, что кто-то еще найдет это полезным.

Failing mutual auth on Android w/ javax.net.ssl.SSLHandshakeException: Handshake failed

I am trying to get a mutual authentication request to work on android. I am testing against my own server so I have a self signed CA and client certificate.

So I will have to allow for untrusted server cert.

Here is what I am doing:

Then the AsyncTask to perform the request:

I have tested this request in a browser and in an iOS client but I cannot get it to work in Android.

I think this is the right way to allow untrusted server certificates:

Not sure why I am getting:

I had to add my own SSLSocketFactory to trust the self signed server cert:

Once I use that I get the following:

javax.net.ssl.SSLHandshakeException: Handshake failed

I am on Lollipop and using apache as my web server. My apache web server config has:

Not really sure what I need to change. I have looked all over and this seems to be the recommend config (for now).

Here is the full stack trace:

Создан 01 июн. 15 2015-06-01 14:03:13 lostintranslation

*»..I am trying to get a mutual authentication request to work on android. «* — probably dumb questions, but is your CA installed on the device? And is the server certificate signed by it? – jww 01 июн. 15 2015-06-01 16:03:40

*». I think this is the right way to allow untrusted server certificates. «* — nope, that’s not it either. [The most dangerous code in the world: validating SSL certificates in non-browser software](https://crypto.stanford.edu/

Читать еще:  Java arraylist в строку

Its a test server. I know a self signed cert is not the way to go for production. I am asking how to mutual handshake with an untrusted server cert. Please re-read the question. – lostintranslation 01 июн. 15 2015-06-01 16:06:14

Server CA is not installed on the device. It doesn’t have to be. Only the client cert needs to be there to complete the handshake. That is why I am loaded a null truststore to allow the untrusted server cert. – lostintranslation 01 июн. 15 2015-06-01 16:10:01

*»Please re-read the question»* — you said you have a CA: *»I have a self signed CA and client certificate.»* — Forgive my ignorance, but what’s the point of running a CA if you don’t certify anything with it? Or why only certify the client certificate, and not the server certificate? – jww 01 июн. 15 2015-06-01 17:41:57

*»I know a self signed cert is not the way to go for production. «* — I did not say that. I implied you should not use untrusted server certificates, meaning they have to be validated. Once you validate them, they can be used. It does not matter if you use your private CA or a public CA. – jww 01 июн. 15 2015-06-01 17:44:20

I am trying to test mutual auth request with a client cert. I could care less about trusting the server right now. – lostintranslation 01 июн. 15 2015-06-01 19:15:58

‘sslContext.init(null, new TrustManager[] , null);’ the key managers are missing if you are using mutual auth – EpicPandaForce 01 июн. 15 2015-06-01 20:57:39

2 ответа

I never put the client cert in the KeyManager:

Создан 01 июн. 15 2015-06-01 20:48:27 lostintranslation

Doh. But a win is a win 🙂 – jww 01 июн. 15 2015-06-01 21:09:22

Yeah double doh, and agreed. Thanks for the help @jww – lostintranslation 01 июн. 15 2015-06-01 23:29:29

I am trying to get a mutual authentication request to work on android.

(comment) Server CA is not installed on the device. It doesn’t have to be. Only the client cert needs to be there to complete the handshake. That is why I am loaded a null truststore to allow the untrusted server cert.

OK, so the easiest solution is to install the CA on the device. I understand you don’t want to do that, and I don’t really blame you. Its not the best solution because it tosses your CA into the mix with others in the CA Zoo.

Since you are doing this all programmatically, then I believe this is your solution: Use PEM Encoded CA Cert on filesystem directly for HTTPS request?. The client will validate the server certificate using your CA, and then continue with the client cert. The CA does not need to be installed on the device.

Another alternative is a custom TrustManager . But I prefer to let the system perform the checks rather than overriding behaviors and checks. There’s a lot of checks you have to perform, and they are error prone. For starters, you have to know what RFCs to go to figure out what those checks are.

I will use a custom TrustManager for Public Key Pinning. There are lots of example of that; see, for example, Certificate and Public Key Pinning on OWASP’s site. You can use pinning and forgo the checks because you don’t need to confer trust. You either talk to the expected server — with public key X; or you don’t — and it does not matter what a third party says (like a CA).

Also be aware that Java and Andro >SSLFactory has some issues, like getInstance(«TLS») will also return SSLv3; and TLS 1.1 and 1.2 will be disabled. To fix that, see Which Cipher Suites to enable for SSL Socket?.

Related to your edit:

This usually works fine:

HIGH will get you everything that’s strong (about 112-bits of security and above).

!aNULL removes anonymous protocols, and !kRSA removes key transport (but not RSA signing) so you are left with Integer and Elliptic Curve Diffie-Hellman. You can see an example of RSA signing below with Au=RSA .

HIGH will also get you some weak/wounded cruft, like MD5 and RC4 , so you explicitly remove them. You also remove unneeded cipher suites, like SRP and PSK .

You can check the ciphers under the string with openssl ciphers -v ‘HIGH:!aNULL:!kRSA:!MD5:!RC4:!SRP:!PSK’ :

By the way, here is your string. All in all, I think it looks good. RC4 will give you the Obsolete Cryptography warnings from some browsers. Just ditch it since the padding oracles in block ciphers are fixed (again. ).

Создан 01 июн. 15 2015-06-01 17:09:29 jww

I am using a custom TrustManager to trust the server cert (trusting all certs). So I still don’t see why I need to embed the server CA. – lostintranslation 01 июн. 15 2015-06-01 19:22:30

Could very well be getInstance(«TLS»). I posted the full stack trace. I had SSL3 disabled, but even after enabling it just to see if it worked I got the same error. – lostintranslation 01 июн. 15 2015-06-01 19:23:56

@lostintranslation — maybe I focused on the wrong thing. I think I focused on *»I will have to allow for untrusted server cert»*. That’s sacred ground for me, and its not necessarily true. Sorry about that. – jww 01 июн. 15 2015-06-01 21:22:33

Ссылка на основную публикацию
Adblock
detector