JAVA - SSL - Сертификаты клиентов - PullRequest
4 голосов
/ 21 января 2012

Я разрабатывал клиент WS с использованием JAVA, и у меня возникла проблема с аутентификацией SSL. WS создаются на WCF, и у меня нет доступа к серверу, они работают через HTTPS и используют клиентский сертификат, который сначала должен быть установлен на клиенте. Ребята с сервера прислали мне сертификат PFX, который я успешно установил в ОС (я использую OS X), и я мог затем получить доступ к WS через браузер (Safari или FF - это те, которые я пробовал, которые ранее не могли получить доступ к WS ). Я думал, что любое приложение в ОС будет использовать эти сертификаты, но когда я попробовал свое приложение JAVA, это не сработало; сначала выдается следующая ошибка:

"javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: сбой построения пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: не удалось найти действительный путь сертификации для запрошенной цели"

Я решил эту проблему, экспортировав сертификат в файл CER и используя инструмент командной строки keytool для добавления сертификата в хранилище ключей "cacerts", которое использует JAVA. Но после того, как эта ошибка ушла, стало появляться следующее: «403, запрещено». Это очевидно, потому что он не использует сертификат клиента SSL для сайта, но я не смог найти способ отправить его на него. Любая помощь будет оценена.

Ниже приведен код, который я использую для публикации на WS:

URL url = new URL(p_url);

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);

conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", contentType);

OutputStream out = conn.getOutputStream(); // on this line it shows the error

Ответы [ 3 ]

5 голосов
/ 21 января 2012

Вы можете создать конкретный SSLContext (используя KeyManager, инициализированный с хранилищем ключей, содержащим ваш клиентский сертификат + закрытый ключ), из которого вы получите SSLSocketFactory, который вы установили в свой HttpsURLConnection, или используйте глобальные настройки.

Вы можете установить следующие системные свойства (для глобальных настроек):

  • javax.net.ssl.keyStore=path/to/keystore.pfx
  • javax.net.ssl.keyStoreType=PKCS12
  • javax.net.ssl.keyStorePassword=xxxxxxxxx

Кроме того, вы можете создать свой собственный KeyManagerFactory / KeyManager, как описано в этом ответе .

Поскольку вы импортировали сертификат сервера в свой cacerts, используйте null для аргумента TrustManager[] SSLContext.init() (он подберет значения по умолчанию).

Кроме того, поскольку вы используете OSX, вы можете использовать KeychainStore напрямую. Для этого используйте ....keyStore=NONE, keyStoreType=KeychainStore и keyStorePassword=- (подойдет любой пароль, так как доступ к ключу будет предоставлен, когда вам потребуется его из ОС). Я не уверен, работает ли это на Лев, хотя. Обратите внимание, что он может потерпеть неудачу, если в вашем магазине имеется более одного сертификата + закрытый ключ (см. эту проблему ).

0 голосов
/ 21 января 2012

Вам нужно загрузить хранилище ключей, которое они вам отправляют, в ваше Java-приложение.
Вы можете загрузить его как файл из файловой системы в объекте Keystore и использовать его. Прочитайте этот пример и особенно часть о KeyManager, т.е. createKeyManagers методе.

Другой вариант - загрузить хранилище ключей из Windows. Подробнее о Windows-MY провайдере

0 голосов
/ 21 января 2012

Похоже, вам, вероятно, нужно настроить собственный SSL SocketFactory,

http://vafer.org/blog/20061010073725/

Я думаю, что с 2006 года все стало лучше, поэтому вам может потребоваться указать несколько свойств в командной строке:

/793675/klientskie-sertifikaty-java-cherez-https-ssl
...