Странная ошибка сертификата при попытке создать клиент веб-службы с защищенного сайта - PullRequest
2 голосов
/ 20 марта 2010

При попытке использовать инструмент AXIS1.4 Wsdl2Java для создания клиентского кода для веб-службы, установленной на защищенном сайте IIS, возникает странная ошибка Когда я запускаю инструмент, я получаю следующее исключение SSL:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No
 name matching XXXXXXX.net found
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1
591)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien
tHandshaker.java:975)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHa
ndshaker.java:123)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:5
16)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.jav
a:454)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.j
ava:884)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SS
LSocketImpl.java:1096)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketIm
pl.java:1123)

Странно то, что эта ошибка возникает только при запуске WSDL2Java и только для этого конкретного сервера. У меня есть другой веб-сервер с такой же настройкой, и там все отлично работает. Я трижды проверил все хранилища ключей, и похоже, что все сертификаты CA загружены правильно. Я попытался использовать другой сервер с такой же настройкой и смог сгенерировать код прокси клиента без проблем. Странно то, что если я использую код, сгенерированный с другого сервера, против странного сервера, все работает отлично. Только Wsdl2Java доставляет мне проблемы.

Ответы [ 5 ]

1 голос
/ 17 июля 2010

Может оказаться полезным использовать свойства системы отладки SSL для изучения этой проблемы:

-Djavax.net.debug=ssl

Если распечатано слишком много, вы можете отфильтровать некоторые вещи, например:

-Djavax.net.debug=ssl,trustmanager

Вывод не обязательно очевиден для чтения, но он должен сказать вам, где ошибка более подробно.

1 голос
/ 20 марта 2010

Очень вероятно несоответствие между DNS-именем хоста (например, machine1.mydomain.tld) ​​и значением CommonName из сертификата, следовательно, CertificateException. Из этого сообщения в блоге :

  • если вы хотите подключиться через IP в качестве имени хоста;
    ваш сертификат должен включать это значение ip в качестве значения альтернативного имени субъекта (типа IPAddress: key = 7).
  • если вы хотите подключиться через DNS в качестве имени хоста;
    Ваш сертификат должен включать это DNS-имя в качестве значения альтернативного имени субъекта (типа DNS: key = 2) или в качестве значения CommonName (CN).
0 голосов
/ 28 марта 2010

Возможно, вам не хватает соответствующего корневого сертификата GlobalSign для Java .

# Import a root or intermediate CA certificate to an existing Java keystore
keytool -import -trustcacerts -alias root -file Thawte.crt -keystore keystore.jks

Другая возможность связана с сочетанием корневого и промежуточного сертификата.Дополнительная информация на сайте GlobalSign :

"Некоторые приложения на основе Apache и Java требуют, чтобы корневой и промежуточный сертификаты были объединены в один сертификат ..."

0 голосов
/ 23 марта 2010

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

В других ответах указано, что вы подключаетесь через IP-адрес. Это не правильный способ делать вещи. Java проверит сертификат по имени хоста, к которому он подключается.

Если вы подключаетесь с использованием IP-адреса, возможно, в вашей среде не настроен DNS. Самый простой способ обойти это - добавить имя хоста в ваш файл hosts. В Windows это находится в 'C: \ Windows \ System32 \ drivers \ etc \ hosts'.

xx.xx.xx.xx      XXXXXXXXXX.net

Это позволит вам использовать имя хоста для получения WSDL через WSDL2Java.

Альтернатива:

Есть альтернатива, если она все еще не работает. Загрузите файл .wsdl с помощью веб-браузера. Пусть WSDL2Java создаст ваши заглушки Java из локального файла на диске, а не на веб-сервере. Сгенерированный код будет идентичным, но для получения WSDL ему не придется проходить через SSL.

0 голосов
/ 20 марта 2010

Если у вас есть сертификат сервера под рукой и установлен openssl, вы можете сбросить содержимое сертификата примерно так:

$ openssl x509 -noout -text -in filename-here.pem

Вы увидите «CN =» как часть темы иесли у него есть расширение altSubjectName в сертификате, вы увидите это ниже под расширениями X509v3, как альтернативное имя субъекта X509v3, и вы будете искать что-то вроде DNS: host-name-here.

Еслисовпадает с именем хоста, к которому вы подключаетесь, затем просто проверьте, подключаетесь ли вы по IP-адресу или по имени хоста через любой интерфейс SSL, через который вы проходите, и убедитесь, что это по имени хоста, а не по IP-адресу.

Если в сертификате нет подходящего имени (совпадающего с именем хоста, к которому вы подключаетесь), некоторые интерфейсы SSL позволяют игнорировать «несоответствие имен».(Я не знаю, как это сделать в вашем конкретном случае.)

РЕДАКТИРОВАТЬ:

Попробуйте подключиться по имени хоста вместо IP-адреса и посмотреть, если есть разница.

Если IP-адрес указан в сертификате, вы увидите что-то вроде IP: xx.xx.xx.xx в поле Альтернативное имя субъекта X509v3 в выводе openssl.

Если IP-адрес отсутствует в списке, выполните командуnslookup из командной строки и сравните выходные данные для рабочего и нерабочего адресов сервера.Это может быть связано с тем, что рабочий сервер соответствует имени хоста (то есть посредством getnetbyaddr).

РЕДАКТИРОВАТЬ 2:

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

...