Как запросить URL-адрес, для проверки подлинности которого требуется сертификат клиента
Мне нужно запросить URL-адрес с сервера, который использует сертификаты клиента для аутентификации и не может найти способ сделать это для моего приложения.
моя проблема в том, что клиент Java, над которым я работаю, имеет файл сертификата, доступный локально, но из-за ограничений на ПК он будет работать на нем, не может установить сертификат в хранилище ключей.
короче говоря, я просто хочу иметь возможность explicilty указать сертификат для использования для URL, который мне нужен возвращать.
какие предложения?
2 ответов
неясно, о каких ограничениях вы говорите. Более конкретно, я не уверен, что вы считаете разницу между локальным файлом сертификата и хранилищем ключей. Большинство хранилищ файлов, так что вы можете быть в состоянии загрузить файл таким образом напрямую, без необходимости установки. Ограничения, связанные с политиками безопасности, используемыми самой JVM (что может помешать вам создать экземпляр KeyStore
s)?
во-первых, это не просто сертификат вам нужен на стороне клиента, но его закрытый ключ. Часто люди используют слово "сертификат" в данном контексте означает, но вы должны убедиться, что ваш файл не содержит сертификат без закрытого ключа. Как правило, вы найдете комбинацию закрытого ключа + сертификата в файле PKCS#12 (.Р12/.pfx), много инструментов импорта / экспорта в этом формате; это также формат хранилища ключей, изначально поддерживаемый Sun JVM (тип PKCS12
).
для того чтобы сделать эту работу, вам чтобы настроить, что делает соединение с соответствующим хранилищем ключей. Клиент SSL / TLS-аутентификация сертификата всегда инициируется сервером: клиент отвечает сертификатом, если он есть (и хочет его использовать). Чтобы настроить его для определенного URL-адреса, вам нужно узнать, что делает соединение (возможно,HttpsURLConnection
) и установите его там (если он не настроен в контексте по умолчанию-даже если он настроен в контексте по умолчанию, он будет использоваться только для серверов, которые запрашивают он.)
чтобы настроить хранилище ключей глобально на JVM (что может быть тем, что ваши ограничения мешают вам делать), вы можете установить javax.net.ssl.keyStore
javax.net.ssl.keyStorePassword
(и связанные) системные свойства. (Потому что пароль может быть виден, лучше не делать этого в командной строке).
эти системные свойства используются для настройки по умолчанию SSLContext
(который используется, часто прозрачно, библиотеками или классами, такими как HttpsURLConnection
построить SSLSocketFactory
а то SSLSocket
, инициализируется этими свойствами).
вы могли бы построить SSLContext
из файла специально для использования для связи. The SSLContext
фактически фабрика для SSLSocketFactory
или SSLEngine
, а вы можете установить SSLSocketFactory
в данной HttpsURLConnection
.
следующее построило бы SSLContext
использование " / path/to / file.p12 " в качестве хранилища ключей (то есть с вашим закрытым ключом и сертификатом, который вы собираетесь отправить) и сохранить настройки по умолчанию для truststore (вам понадобится чтобы поймать исключение для входного потока тоже).
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream("/path/to/file.p12");
ks.load(fis, "password".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
оттуда вы можете настроить соединение такой (если это то, что вы используете):
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (connection instanceof HttpsURLConnection) {
((HttpsURLConnection)connection)
.setSSLSocketFactory(sc.getSSLSocketFactory());
}
некоторые библиотеки позволят вам пройти SSLContext
напрямую (Apache HTTP Client 4 поддерживает это, и это можно сделать с помощью Apache HTTP Client 3 используя этот.)
обратите внимание, что вам не нужно указывать пароль в качестве прямого параметра при загрузке хранилища ключей, вы также можете использовать обратный вызов (возможно, лучше с точки зрения GUI).
возможно библиотека может помочь (но это не обязательно): вы можете использовать KeystoreLoader
для своих помощников для этого. Есть также SSLContextFactories в этих библиотеках (но вам, вероятно, не понадобится ни одна из оболочек, поскольку они, как правило, предназначены для настройки управления доверием или выбора ключа).
это, как правило, как использование сертификата клиента настроено, но трудно предоставить более подробную информацию без разъяснений относительно того, каковы ваши ограничения (и какие библиотеки вы используете).
вы можете изменить хранилище ключей JSSE по умолчанию через свойство при вызове приложения,-Djavax.net.ssl.keystore=somefile
.
таким образом, вы можете импортировать сертификат с помощью команды keytool в хранилище ключей и вызвать приложение, указывающее на это, например
keytool -importcert -file mycert -keystore mystore
java -Djavax.net.ssl.keystore=mystore ...