Ответ 1
Не ясно, какие ограничения вы говорите. В частности, я не уверен, что вы считаете разницей между локальным файлом сертификата и хранилищем ключей. Большинство хранилищ ключей основаны на файлах, поэтому вы можете загрузить этот файл напрямую, без необходимости установки. Являются ли ограничения, связанные с политиками безопасности, используемыми самой 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
эффективно factory для 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 с помощью этого.)
Обратите внимание, что вам не нужно указывать пароль как прямой параметр при загрузке хранилища ключей, вы также можете использовать обратный вызов (возможно, лучше с точки зрения графического интерфейса пользователя).
Возможно, эта библиотека могла бы помочь (но это не обязательно): вы могли бы использовать KeystoreLoader
для своих помощников. В этих библиотеках также есть SSLContextFactories (но вам, вероятно, не понадобится ни одна из оболочек, поскольку они, как правило, предназначены для настройки управления доверием или выбора ключа).
Как правило, используется настройка клиентского сертификата, но трудно предоставить более подробную информацию без каких-либо разъяснений относительно того, какие именно ограничения (и какие библиотеки вы используете).