Как мне подписать HTTP-запрос сертификатом X.509 в Java? - PullRequest
6 голосов
/ 26 мая 2010

Как мне выполнить HTTP-запрос и подписать его сертификатом X.509, используя Java?

Я обычно программирую на C #. Теперь я хотел бы сделать что-то похожее на следующее, только на Java:

 private HttpWebRequest CreateRequest(Uri uri, X509Certificate2 cert) 
 {
     HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
     request.ClientCertificates.Add(cert);
     /* ... */
     return request;
 }

В Java я создал экземпляр java.security.cert.X509Certificate, но не могу понять, как связать его с HTTP-запросом. Я могу создать HTTP-запрос с использованием экземпляра java.net.URL, но мне кажется, что я не могу связать свой сертификат с этим экземпляром (и я не уверен, что использование java.net.URL даже уместно).

Ответы [ 3 ]

2 голосов
/ 27 мая 2010

Я не программист на C #, но я предполагаю, что код выполняет вызов с использованием HTTPS / TLS и предоставляет сертификат клиента для аутентификации? Ака, ты не спрашиваешь, как использовать WS-Security, верно?

В таком случае, я думаю, ответы здесь и здесь будут вам полезны. Вам нужно использовать утилиту openssl для импорта вашего сертификата в хранилище ключей клиента p12. Если на вашем сервере используется нестандартный ЦС или самозаверяющий сертификат, вам также необходимо настроить доверенное хранилище клиента с этими сертификатами.

На этом этапе посмотрите на вопросы, которые я связал: вам нужно будет указать целый ряд аргументов JVM. Наконец, попробуйте повторить вызов (используя стандартные объекты Java или httpclient). Клиент должен принять сертификат сервера, если ваше доверенное хранилище правильно и сервер должен запросить сертификат клиента. Если ваше хранилище ключей настроено правильно, клиент, прошедший проверку подлинности с помощью сертификата клиента X.509, будет в порядке.

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

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

В Java java.security.cert.X509Certificate - это на самом деле просто сертификат (сертификат открытого ключа, без закрытого ключа). На стороне клиента вам нужно настроить закрытый ключ с ним. Предполагая, что ваш закрытый ключ и сертификат находятся в хранилище ключей (для упрощения, я предполагаю, что есть только один подходящий сертификат с его закрытым ключом, возможно, с другими сертификатами в цепочке, в этом хранилище ключей), и что вы используете значение по умолчанию трастовый магазин:

KeyStore ks = ...
/* load the keystore */

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, password);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);

URL url = new URL("https://example/");
HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();

connection.setSSLSocketFactory(sslContext.getSSLSocketFactory());

Другие библиотеки позволят вам установить SSLContext или KeyStore немного по-другому, но принципы должны быть такими же.

(Вы также можете использовать системные свойства javax.net.ssl.keyStore, если это необходимо.)

1 голос
/ 27 мая 2010

Я бы порекомендовал библиотеку HttpClient с открытым исходным кодом от Apache Commons. Охватывает этот вариант использования и многие другие.

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