Не ясно, о каких ограничениях вы говорите. В частности, я не уверен, что вы считаете разницу между локальным файлом сертификата и хранилищем ключей. Большинство хранилищ ключей основаны на файлах, поэтому вы можете загрузить этот файл напрямую, без необходимости установки. Связаны ли ограничения с политиками безопасности, используемыми самой JVM (что может помешать вам создавать KeyStore
s)?
Во-первых, вам нужен не только сертификат на стороне клиента, но и его закрытый ключ. Часто люди используют слово «сертификат» в этом контексте, чтобы обозначать и то и другое, но вам нужно убедиться, что ваш файл не содержит сертификат без закрытого ключа. Как правило, вы найдете комбинацию секретный ключ + сертификат в файле PKCS # 12 (.p12 / .pfx), множество инструментов для импорта / экспорта в этом формате; это также формат хранилища ключей, изначально поддерживаемый Sun JVM (тип PKCS12
).
Чтобы это работало, вам нужно настроить соединение с соответствующим хранилищем ключей. Проверка подлинности клиента-сертификата SSL / TLS всегда инициируется сервером: клиент отвечает сертификатом, если он есть (и хочет его использовать). Чтобы настроить его для определенного URL-адреса, вам необходимо выяснить, из-за чего устанавливается соединение (возможно, HttpsURLConnection
), и установить его там (если оно не настроено в контексте по умолчанию - даже если оно настроено в контексте по умолчанию, оно будет использоваться только для серверов, которые его запрашивают).
Чтобы настроить хранилище ключей глобально на JVM (что может быть тем, что вам мешают делать ваши ограничения), вы можете установить системные свойства javax.net.ssl.keyStore
javax.net.ssl.keyStorePassword
(и связанные с ними). (Поскольку пароль может быть виден, лучше не делать это в командной строке).
Эти системные свойства используются для конфигурации по умолчанию SSLContext
(которая часто используется прозрачно для библиотек или классов, таких как HttpsURLConnection
, для построения SSLSocketFactory
, а затем SSLSocket
, инициализированных этими свойствами ).
Вы можете собрать SSLContext
из вашего файла специально для использования для этого соединения. SSLContext
фактически является фабрикой для SSLSocketFactory
или SSLEngine
, и вы можете установить SSLSocketFactory
в данном HttpsURLConnection
.
Следующее создаст SSLContext
с использованием "/path/to/file.p12" в качестве хранилища ключей (то есть с вашим закрытым ключом и сертификатом, который вы собираетесь отправить) и сохранит настройки по умолчанию для хранилище доверенных сертификатов (вам также нужно перехватить исключение для входного потока).
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 , используя это .)
Обратите внимание, что вам не нужно указывать пароль в качестве прямого параметра при загрузке хранилища ключей, вы также можете использовать обратный вызов (возможно, лучше с точки зрения графического интерфейса пользователя).
Возможно, эта библиотека могла бы помочь (но это не обязательно): вы могли бы использовать KeystoreLoader
для ее помощников, чтобы сделать это. В этих библиотеках также есть SSLContextFactories (но вам, вероятно, не понадобятся никакие из оболочек, так как они предназначены для настройки доверительного управления или выбора ключа).
Обычно так настраивается использование сертификата клиента, но трудно предоставить более подробную информацию без пояснений относительно того, какие именно ограничения существуют (и какие библиотеки вы используете).