У меня проблема с авторизованным соединением SSL. Я создал действие Struts, которое подключается к внешнему серверу с помощью сертификата Client Authorized SSL. В своем действии я пытаюсь отправить некоторые данные на сервер банка, но безуспешно, потому что в результате с сервера произошла следующая ошибка:
error: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Мой метод из моего класса Action, который отправляет данные на сервер
//Getting external IP from host
URL whatismyip = new URL("http://automation.whatismyip.com/n09230945.asp");
BufferedReader inIP = new BufferedReader(new InputStreamReader(whatismyip.openStream()));
String IPStr = inIP.readLine(); //IP as a String
Merchant merchant;
System.out.println("amount: " + amount + ", currency: " + currency + ", clientIp: " + IPStr + ", description: " + description);
try {
merchant = new Merchant(context.getRealPath("/") + "merchant.properties");
} catch (ConfigurationException e) {
Logger.getLogger(HomeAction.class.getName()).log(Level.INFO, "message", e);
System.err.println("error: " + e.getMessage());
return ERROR;
}
String result = merchant.sendTransData(amount, currency, IPStr, description);
System.out.println("result: " + result);
return SUCCESS;
Мой файл merchant.properties:
bank.server.url=https://-servernameandport-/
https.cipher=-cipher-
keystore.file=-key-.jks
keystore.type=JKS
keystore.password=-password-
ecomm.server.version=2.0
encoding.source=UTF-8
encoding.native=UTF-8
Впервые я подумал, что это проблема с сертификатом, я преобразовал его из .pfx в .jks, но у меня та же ошибка, без изменений.
Ответы:
Рукопожатие могло произойти по разным причинам:
Так как основной сбой не может быть точно определен, лучше включить
-Djavax.net.debug=all
флаг, чтобы разрешить отладку установленного соединения SSL. С включенной отладкой вы можете определить, какая активность в рукопожатии не удалась.Обновить
Судя по имеющимся подробностям, похоже, что проблема связана с неполным путем доверия сертификата между сертификатом, выданным серверу, и корневым центром сертификации. В большинстве случаев это происходит из-за того, что сертификат корневого ЦС отсутствует в хранилище доверенных сертификатов, что приводит к ситуации, когда путь доверия сертификату не может существовать; сертификат по существу не доверен клиенту. Браузеры могут выдавать предупреждение, чтобы пользователи могли игнорировать это, но то же самое не относится к клиентам SSL (таким как класс HttpsURLConnection или любой клиентской библиотеке HTTP, такой как клиент Apache HttpComponents ).
Большинство этих клиентских классов / библиотек полагались бы на хранилище доверия, используемое JVM для проверки сертификата. В большинстве случаев это будет
cacerts
файл в каталоге JRE_HOME / lib / security. Если местоположение хранилища доверенных сертификатов указано с помощью системного свойства JVMjavax.net.ssl.trustStore
, то хранилище по этому пути обычно является хранилищем, используемым клиентской библиотекой. Если вы сомневаетесь, взгляните на свойMerchant
класс и выясните, какой класс / библиотеку он использует для установления соединения.Добавление сертификата сервера, выдающего CA, в это хранилище доверия должно решить проблему. Вы можете обратиться к моему ответу на связанный вопрос о получении инструментов для этой цели, но для этой цели достаточно утилиты Java keytool .
Предупреждение. Хранилище доверенных сертификатов - это список всех доверенных центров сертификации. Если вы вставите сертификат, который не принадлежит ЦС, которому вы не доверяете, то соединения SSL / TLS с сайтами, имеющими сертификаты, выданные этим объектом, могут быть расшифрованы, если доступен закрытый ключ.
Обновление № 2: Понимание вывода трассировки JSSE
Склад ключей и хранилища доверенных сертификатов, используемые JVM, обычно перечислены в самом начале, примерно так:
Если используется неправильное хранилище доверенных сертификатов, вам необходимо повторно импортировать сертификат сервера в правильный или перенастроить сервер для использования указанного в списке (не рекомендуется, если у вас несколько JVM, и все они используются для разных необходимо).
Если вы хотите проверить, содержит ли список доверенных сертификатов требуемые сертификаты, существует раздел для него, который начинается с:
Вам нужно будет искать, является ли ЦС сервера субъектом.
Процесс рукопожатия будет иметь несколько заметных записей (вам нужно знать SSL, чтобы понять их подробно, но для отладки текущей проблемы достаточно знать, что handshake_failure обычно сообщается в ServerHello.
1. ClientHello
О серии записей будет сообщено при инициализации соединения. Первое сообщение, отправленное клиентом в настройке соединения SSL / TLS, - это сообщение ClientHello, которое обычно регистрируется в журналах как:
Обратите внимание на используемые комплекты шифров. Это , возможно , придется согласиться с записью в файле merchant.properties, по той же конвенции могут быть использованы библиотекой банка. Если используется другое соглашение, нет причин для беспокойства, так как ServerHello сообщит об этом, если набор шифров несовместим.
2. ServerHello
Сервер отвечает ServerHello, который будет указывать, можно ли продолжить установку соединения. Записи в журналах обычно бывают следующего типа:
Обратите внимание на набор шифров, который он выбрал; это лучший набор, доступный как для сервера, так и для клиента. Обычно набор шифров не указывается в случае ошибки. Сертификат сервера (и, необязательно, всей цепочки) отправляется сервером и может быть найден в записях как:
Если проверка сертификата прошла успешно, вы найдете запись, похожую на:
Один из описанных выше шагов не был бы успешным, что привело бы к handshake_failure, поскольку рукопожатие обычно завершается на этом этапе (не совсем, но последующие этапы рукопожатия обычно не вызывают сбой рукопожатия). Вам необходимо выяснить, на каком этапе произошел сбой, и опубликовать соответствующее сообщение в качестве обновления вопроса (если вы уже не поняли сообщение и не знаете, что делать, чтобы его решить).
источник
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
команду для распечатки содержимого. Затем проверьте, соответствуют ли сертификаты в каскадах CA сертификата банка.changeit
. Если только это не было изменено.Установка Расширения Java Cryptography (JCE) Unlimited Strength ( для JDK7 | для JDK8 ) может исправить эту ошибку. Разархивируйте файл и следуйте инструкциям, чтобы установить его.
источник
Ошибка квитирования может быть ошибочной реализацией протокола TLSv1.
В нашем случае это помогло с Java 7:
JVM будет вести переговоры в этом порядке. Серверы с последним обновлением будут работать с 1.2, а с ошибками - до v1, и это работает с аналогичным v1 в Java 7.
источник
Это также может произойти, когда клиенту необходимо представить сертификат. После перечисления сервером цепочки сертификатов может произойти следующее:
3. Запрос сертификата Сервер выдаст запрос сертификата от клиента. В запросе будут перечислены все сертификаты, которые принимает сервер.
4. Цепочка сертификатов клиента Это сертификат, который клиент отправляет на сервер.
Если в цепочке нет сертификата, а сервер требует его, вы получите здесь ошибку рукопожатия. Вероятная причина - путь к вашему сертификату не найден.
5. Проверка сертификата . Клиент просит сервер проверить сертификат.
Этот шаг произойдет только в том случае, если вы отправляете сертификат.
6. Готово . Сервер ответит подтверждением.
источник
Я не думаю, что это решит проблему для первого спрашивающего, но для гуглеров, приходящих сюда за ответами:
В обновлении 51 java 1.8 по умолчанию запрещала [1] шифры RC4, как мы можем видеть на странице примечаний к выпуску:
Если ваш сервер отдает предпочтение этому шифру (или использует только этот шифр), это может вызвать
handshake_failure
ошибку на java.Вы можете протестировать подключение к серверу, включив шифры RC4 (сначала попробуйте без
enabled
аргументов, чтобы увидеть, запускает ли ahandshake_failure
, затем установитеenabled
:1 - https://www.java.com/en/download/faq/release_changes.xml
источник
У меня есть эта ошибка, когда я пытался использовать JDK 1.7. Когда я обновил свой JDK до jdk1.8.0_66, все стало работать нормально.
Итак, самым простым решением этой проблемы может быть обновление JDK, и он может начать хорошо работать.
источник
В моем случае сертификат импортируется, ошибка остается, решил это, добавив
System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
перед подключениемисточник
Предполагая, что вы используете правильные протоколы SSL / TLS, правильно настроили свои
keyStore
иtrustStore
и подтвердили, что с самими сертификатами не существует никаких проблем, вам может потребоваться усилить свои алгоритмы безопасности .Как упоминалось в ответе Vineet , одна из возможных причин, по которой вы получаете эту ошибку, связана с использованием несовместимых наборов шифров. Обновив мои
local_policy
иUS_export_policy
jar-файлы вsecurity
папке JDK, используя те, которые предоставлены в Java Cryptography Extension (JCE) , я смог успешно завершить рукопожатие.источник
Сегодня я столкнулся с той же проблемой с клиентом OkHttp для ПОЛУЧЕНИЯ URL-адреса на основе https. это было вызвано несоответствием версии протокола Https и метода шифрования на стороне сервера и на стороне клиента .
1) проверьте версию протокола https и метод шифрования вашего сайта.openssl>s_client -connect your_website.com:443 -showcerts
Вы получите много подробной информации, основная информация указана следующим образом:
2) настройте свой http-клиент, например, в клиенте OkHttp :Получим то, что хотим.
источник
Я нашел HTTPS-сервер, который отказал таким образом, если мой клиентский процесс Java был настроен с
Не удалось
handshake_failure
установить соединение с послеServerHello
успешного завершения, но до начала потока данных.Не было четкого сообщения об ошибке, которое идентифицировало проблему, ошибка просто выглядела как
Я изолировал проблему, попробовав с
-Djsse.enableSNIExtension=false
опцией " " и без нееисточник
Мой был
TLS
ошибка несовместимости версий.Раньше
TLSv1
я его менял,TLSV1.2
это решило мою проблему.источник
Я использую http-клиент com.google.api. Когда я общаюсь с внутренним сайтом компании, у меня возникает эта проблема, когда я по ошибке использовал https вместо http.
источник
У меня была аналогичная проблема; при обновлении до Apache HTTPClient 4.5.3 это исправлено.
источник
Ugg! Для меня это оказалось просто проблемой версии Java. Я получил ошибку рукопожатия, используя JRE 1.6, и все отлично работало с JRE 1.8.0_144.
источник
Отказ от ответственности: я не знаю, будет ли ответ полезен для многих людей, просто поделитесь им, потому что это может быть.
Я получал эту ошибку при использовании Parasoft SOATest для отправки запроса XML (SOAP).
Проблема заключалась в том, что я выбрал неправильный псевдоним из раскрывающегося списка после добавления сертификата и его аутентификации.
источник
В моем случае сайт просто может использовать TLSv1.2. и я использую apache httpclient 4.5.6, я использую этот код и устанавливаю jce для решения этой проблемы (JDK1.7):
ОКО
jdk7 http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
jdk 8 http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
код:
источник
Для устранения неполадок с точки зрения разработчика (элемент 1) и системного администратора (элемент 2 и 3):
-Djavax.net.debug=ssl:handshake:verbose
.sudo apt install ssldump
или скомпилируйте из исходного кода, перейдя по этой ссылке, если вы заметилиUnknown value
в шифровании при выполнении шага ниже.sudo ssldump -k <your-private-key> -i <your-network-interface>
Пример неработающего рукопожатия журнала ssldump:
Пример успешного рукопожатия журнала ssldump
Пример неработающего журнала Java
источник
В моем случае у меня была одна проблема с версией 1.1. Я легко воспроизвел проблему с помощью curl. Сервер не поддерживает более ранние версии, чем TLS1.2.
Это получило проблему с рукопожатием:
С версией 1.2 все работало нормально:
На сервере был запущен Weblogic, и добавление этого аргумента в setEnvDomain.sh позволило ему работать с TLSv1.1:
источник
Эта проблема возникает из-за версии java. Я использовал 1.8.0.231 JDK и получал эту ошибку. Я ухудшил свою версию java с 1.8.0.231 до 1.8.0.171, теперь она работает нормально.
источник