Как я выполняю Запрос 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 я создал a java.security.cert.X509Certificate
экземпляр, но я не могу выяснить, как связать его к Запросу HTTP. Я могу создать Запрос HTTP с помощью java.net. Экземпляр URL, но я, кажется, не могу связать свой сертификат с тем экземпляром (и я не уверен ли использование java.net. URL является даже соответствующим).
Я не программист C#, но я предполагаю, что код делает вызов, используя HTTPS/TLS и предоставляет сертификат клиента для аутентификации? Вы же не спрашиваете, как использовать WS-Security, верно?
В таком случае, я думаю, ответы здесь и здесь будут вам полезны. Вам нужно использовать утилиту openssl для импорта сертификата в хранилище ключей клиента p12. Если ваш сервер использует нестандартный CA или самоподписанный сертификат, вам нужно будет настроить клиентское хранилище с этими сертификатами.
На этом этапе посмотрите на вопросы, на которые я дал ссылку: вам нужно будет указать целый ряд аргументов JVM. Наконец, попробуйте сделать вызов снова (используя стандартные объекты Java или httpclient). Клиент должен принять сертификат сервера, если ваше хранилище доверия правильно, а сервер должен запросить сертификат клиента. Если ваше хранилище ключей настроено правильно, клиент аутентифицируется с помощью клиентского сертификата X.509, и вы будете готовы к работе.
Я бы порекомендовал библиотеку HttpClient с открытым исходным кодом от Apache Commons. Охватывает этот вариант использования и многие другие.
Похоже, что вы пытаетесь использовать 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
, если это уместно)