Ошибка рукопожатия могла произойти по разным причинам:
- Несовместимые комплекты шифров, используемые клиентом и сервером.Это потребует от клиента использования (или включения) набора шифров, поддерживаемого сервером.
- Используются несовместимые версии SSL (сервер может принимать только TLS v1, в то время как клиент может использовать толькоSSL v3).Опять же, клиент может убедиться, что он использует совместимую версию протокола SSL / TLS.
- Неполный путь доверия для сертификата сервера;сертификат сервера, вероятно, не является доверенным клиентом.Это обычно приводит к более подробной ошибке, но это вполне возможно.Обычно исправление заключается в импорте сертификата CA сервера в хранилище доверенных сертификатов клиента.
- Сертификат выдан для другого домена.Опять же, это привело бы к более подробному сообщению, но я изложу здесь исправление в случае, если это является причиной.В этом случае разрешение будет заключаться в том, чтобы сервер (по-видимому, не ваш) использовал правильный сертификат.
Поскольку не удается точно определить основную неисправность, лучше включить-Djavax.net.debug=all
флаг, чтобы включить отладку установленного соединения SSL.С включенной отладкой вы можете точно определить, какая активность в рукопожатии не удалась.
Обновление
На основании доступных подробностей, похоже, что проблема связана сна неполный путь доверия сертификата между сертификатом, выданным серверу, и корневым центром сертификации.В большинстве случаев это происходит из-за того, что сертификат корневого ЦС отсутствует в хранилище доверенных сертификатов, что приводит к ситуации, когда путь доверия для сертификата не может существовать;сертификат по существу не доверен клиенту.Браузеры могут выдавать предупреждение, чтобы пользователи могли игнорировать это, но это не относится к клиентам SSL (например, класс HttpsURLConnection или любая клиентская библиотека HTTP, например Apache HttpComponents Client ).
Большинство этих клиентских классов / библиотек полагались бы на хранилище доверия, используемое JVM для проверки сертификата.В большинстве случаев это будет файл cacerts
в каталоге JRE_HOME / lib / security.Если местоположение хранилища доверенных сертификатов было указано с помощью системного свойства JVM javax.net.ssl.trustStore
, то хранилище по этому пути обычно является хранилищем, используемым клиентской библиотекой.Если вы сомневаетесь, взгляните на ваш Merchant
класс и выясните, какой класс / библиотеку он использует для установления соединения.
Добавление сертификата сервера, выдающего CA, к этому хранилищу доверия должно разрешитьсяэта проблема.Вы можете обратиться к моему ответу на связанный вопрос о получении инструментов для этой цели, но для этой цели достаточно утилиты Java keytool .
Предупреждение : хранилище доверенных сертификатов - это список всех доверенных центров сертификации.Если вы вставите сертификат, который не принадлежит ЦС, которому вы не доверяете, то соединения SSL / TLS с сайтами, имеющими сертификаты, выданные этим объектом, могут быть расшифрованы, если доступен закрытый ключ.
Обновление № 2: Общие сведения о выводе трассировки JSSE
Склад ключей и хранилища доверенных сертификатов, используемые JVM, обычно перечислены в самом начале, примерно так:
keyStore is :
keyStore type is : jks
keyStore provider is :
init keystore
init keymanager of type SunX509
trustStore is: C:\Java\jdk1.6.0_21\jre\lib\security\cacerts
trustStore type is : jks
trustStore provider is :
Если используется неправильное хранилище доверенных сертификатов, вам потребуется повторно импортировать сертификат сервера в правильный или перенастроить сервер для использования указанного в списке (не рекомендуется, если у вас несколько JVM, и все они используютсядля различных нужд).
Если вы хотите проверить, содержит ли список доверенных сертификатов требуемые сертификаты, существует раздел для него, который начинается как:
adding as trusted cert:
Subject: CN=blah, O=blah, C=blah
Issuer: CN=biggerblah, O=biggerblah, C=biggerblah
Algorithm: RSA; Serial number: yadda
Valid from SomeDate until SomeDate
ВыНужно будет искать, является ли ЦС сервера темой.
Процесс рукопожатия будет иметь несколько заметных записей (вам нужно знать SSL, чтобы понять их подробно, но для отладки текущей проблемы достаточно знать, что в ServerHello обычно сообщается о handshake_failure) .
1. ClientHello
О серии записей будет сообщено при инициализации соединения. Первое сообщение, отправленное клиентом в настройке соединения SSL / TLS, - это сообщение ClientHello, которое обычно регистрируется в журналах как:
*** ClientHello, TLSv1
RandomCookie: GMT: 1291302508 bytes = { some byte array }
Session ID: {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods: { 0 }
***
Обратите внимание на используемые комплекты шифров. Для этого может потребоваться согласие с записью в вашем файле merchant.properties, поскольку такое же соглашение может быть использовано библиотекой банка. Если используется другое соглашение, нет причин для беспокойства, так как ServerHello сообщит об этом, если набор шифров несовместим.
2. ServerHello
Сервер отвечает ServerHello, который будет указывать, можно ли продолжить установку соединения. Записи в журналах обычно имеют следующий тип:
*** ServerHello, TLSv1
RandomCookie: GMT: 1291302499 bytes = { some byte array}
Cipher Suite: SSL_RSA_WITH_RC4_128_SHA
Compression Method: 0
***
Обратите внимание на набор шифров, который он выбрал; это лучший набор, доступный как для сервера, так и для клиента. Обычно набор шифров не указывается в случае ошибки. Сертификат сервера (и, возможно, всей цепочки) отправляется сервером и может быть найден в записях как:
*** Certificate chain
chain [0] = [
[
Version: V3
Subject: CN=server, O=server's org, L=server's location, ST =Server's state, C=Server's country
Signature Algorithm: SHA1withRSA, OID = some identifer
.... the rest of the certificate
***
Если проверка сертификата прошла успешно, вы найдете запись, похожую на:
Found trusted certificate:
[
[
Version: V1
Subject: OU=Server's CA, O="Server's CA's company name", C=CA's country
Signature Algorithm: SHA1withRSA, OID = some identifier
Один из описанных выше шагов не был бы успешным, что привело бы к handshake_failure, поскольку рукопожатие обычно завершается на этом этапе (не совсем, но последующие этапы рукопожатия обычно не вызывают сбой рукопожатия). Вам необходимо выяснить, на каком этапе произошел сбой, и опубликовать соответствующее сообщение в качестве обновления вопроса (если вы уже не поняли сообщение и не знаете, что делать, чтобы его решить).