Что может привести к успешному согласованию SSL в .NET, но не в Java? - PullRequest
1 голос
/ 26 августа 2010

Нам нужно создать клиент веб-службы, использующий Apache CXF на Java.Дело в том, что я не могу заставить сеанс SSL работать правильно.Либо он вообще терпит неудачу, либо сервер не может расшифровать то, что ему отправлено, после передачи данных приложения, либо мне не удается прочитать ответы с сервера.

Однако при попытке выполнить ту же транзакцию с использованием простого клиента тестирования мылавстроенный в .NET все работает гладко.

Сервер использует двойную аутентификацию.

Все на основе сертификатов (x509) хранится в хранилище сертификатов Windows (windows-MY и windows-ROOT)


редактировать да, двойная аутентификация действительно является аутентификацией клиента И сервера.

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

PLatform клиента CXF 2.2.9, сервер Sun JDK 1.6_21. IIS 6 ASP.NET, к сожалению, это все, что я мог собрать, у меня нет контроля над сервером, и я должен использовать его как есть.

обновление Сейчас я пользуюсь хранилищем ключей JKS, но проблема по-прежнему возникает.Кажется, клиент не отправляет свой сертификат на сервер как часть процесса аутентификации.В результате я получаю сообщение об ошибке 403.7 от сервера.

Забавно, что я получаю это сообщение об ошибке в виде HTML-страницы, которую необходимо сначала расшифровать, прежде чем она станет читаемой!

Ответы [ 3 ]

4 голосов
/ 26 августа 2010

Предположительно, под двойной аутентификацией вы подразумеваете, что используете аутентификацию сертификата клиента в дополнение к аутентификации сертификата сервера (что более распространено).

Было бы полезно узнать, какие версии платформ используются с обеих сторон и какие исправления были применены.

Возможно, что часть проблемы связана с исправлением повторного согласования до CVE-2009-3555 (или без исправления).

Проблема заключается в недостатке первоначального проекта повторного согласования в TLS, который использовался для повторного согласования сертификата клиента. Существует два способа получения клиентского сертификата: либо сервер запрашивает его во время первоначального рукопожатия TLS, либо он запрашивает его во время последующего рукопожатия (например, когда он выяснил, на что был направлен запрос и / или при попытке доступа к определенной запретной зоне). Второй метод - это повторные переговоры. К сожалению, в этом отношении был обнаружен недостаток безопасности при разработке протокола TLS, который с тех пор был исправлен благодаря расширению TLS, описанному в RFC 5746 .

Когда недостаток был впервые обнаружен (примерно в ноябре 2009 года), некоторые платформы и библиотеки, такие как Sun Java или OpenSSL, развернули быстрое исправление, которое просто запретило любое повторное согласование (поэтому сработало бы только первоначальное согласование сертификата клиента) , Позже, после написания RFC 5746, эти библиотеки начали внедрять реализации, поддерживающие это расширение.

Насколько я знаю, по умолчанию Microsoft в IIS и ее веб-инфраструктуре использовала повторное согласование, а не первоначальное согласование. Кроме того, не было развернуто первоначальное исправление, чтобы отключить повторное согласование (эффективно сохраняя известную уязвимость). Он только выпустил патч (по-прежнему допускающий старые реализации по умолчанию) совсем недавно: Бюллетень по безопасности Microsoft MS10-049 - критический .

Существует также объяснение проблемы в этом блоге безопасности Microsoft: http://blogs.technet.com/b/srd/archive/2010/08/10/ms10-049-an-inside-look-at-cve-2009-3555-the-tls-renegotiation-vulnerability.aspx

По сути, если вы пытаетесь установить связь с сервером, который поддерживает только старый стиль согласования из стека, который имеет только новый стиль повторного согласования или вообще не повторяет согласование, это не сработает.

Если ваш сервер работает с использованием IIS или аналогичной среды, возможно, вы сможете включить начальное согласование сертификата клиента с помощью netsh и его опции clientcertnegotiation=enable.

3 голосов
/ 26 августа 2010

Java не зависит от хранилища сертификатов ОС и должна использовать свое собственное.

Это импортирует ваши самозаверяющие сертификаты.

cd JAVA_HOME/jre/lib/security
keytool -import -file server_cert.cer -keystore cacerts
0 голосов
/ 27 августа 2010

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

Правильный вопрос должен был быть

Как заставить Java выполнять Аутентификацию на стороне клиента на сервере, который не запрашивает Запрос сертификатов?

ответ на самом деле у нас под носом, но чтобы получить ответ, нужен правильный вопрос !!

Большое спасибо Бруно, который предоставил очень полезную информацию.

решение можно в значительной степени суммировать в следующих двух вопросах:

Проверка подлинности сертификата клиента Java HTTPS

Проверка подлинности клиента SSL, вызывающая ошибку 403.7 из IIS

Хотя клиент «не должен» отправлять сертификат, если его не спрашивают, я обнаружил, что путем настройки сертификата клиента в хранилище ключей должно содержаться следующее:

  • Сертификат клиента со всеми расширениями
  • Закрытый ключ клиента
  • Объединение полной цепочки сертификации клиента.

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

Надеюсь, это поможет кому-то еще, кто может застрять в той же проблеме, обязательно побеспокоите меня, пока я не достиг корня зла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...