2013-04-12 3 views
1

Я пытаюсь сделать подключение https с помощью встроенных функций java для этого (HttpURLConnection). Но я получаю это исключение:Открытие пути сертификата в Java

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) 
... 
... 

Моя цепь сертификата:

Root certificate -> Intermediate certificate -> Web server certificate

Используемый сертификат является правильным по смыслу «открытия Путь». Ядром доверия является Root-сертификат, который импортируется в хранилище java в моей системе. Промежуточный сертификат не ... BUT

  1. Промежуточный сертификат подписан корнем, которому я доверяю, поэтому я тоже доверяю промежуточному. Сертификат
  2. Web-сервер подписан промежуточный сертификат, который я доверяю (точка 1)

Так проверка должна пройти успешно? У меня что-то не так?

Где-то я прочитал это:

Браузеры могут сделать автоматическое обнаружение, сервер-сервер не делает.

но отсутствие этой функциональности очень прост. Есть ли четкий способ сделать это auto-discovery?

* * Update

Да, это был вопрос, GPI. Я был в замешательстве, потому что браузеры могли проверить сертификат сервера, но java-приложение не могло. Причиной такого поведения было:

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

Решение может быть:

  • сервера для возврата всей цепи сертификат системы
  • промежуточного сертификата должны быть добавлены в Java хранилища доверенного

ответ

3

Я уверен, что вы уже проверили вашу цепь, таким образом, мы можем считать само собой разумеющимся, что RootCert подписал IntermediateCert и IntermediateCert подписал ServerCert с действительным именем X500 цепочки и все ...

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

В вашем случае, если вы доверяете только корневому сертификату, то сервер должен рекламировать остальную часть цепочки сертификатов (промежуточную и конечную). Если никто никогда «не дает» HTTP-клиенту промежуточный сертификат, то клиент не будет работать с . Корень до Сервер без знания Промежуточное невозможно.

Фактически вы можете увидеть, какая цепочка сертификатов сервера, запустив ваш клиент с опцией -Djavax.net.debug=all. Если цепочка имеет длину 1, то ваш сервер объявляет только окончательный сертификат, и клиент не может догадаться, существует ли промежуточный сертификат.

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

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

0

Для подключения через Https вы необходимо использовать объект HttpsURLConnection. Вы не можете создать соединение с объектом HttpURLConnection.

+1

URL serverUrl = новый URL (serverAddress); соединение = (HttpURLConnection) serverUrl.openConnection(); Да, возвращенный объект HttpsURLConnection, но он наследует HttpURLConnection. – joro

Смежные вопросы