Использование нескольких клиентских сертификатов SSL в Java с одним и тем же хостом - PullRequest
7 голосов
/ 20 мая 2009

В моем приложении Java мне нужно подключиться к одному и тому же хосту, используя SSL, но каждый раз используя разные сертификаты. Причина, по которой мне нужно использовать разные сертификаты, заключается в том, что удаленный сайт использует свойство идентификатора пользователя, встроенное в сертификат, для идентификации клиента.

Это серверное приложение, которое работает в 3 разных операционных системах, и мне нужно иметь возможность переключать сертификаты без перезапуска процесса.

Другой пользователь предложил импортировать несколько сертификатов в одно хранилище ключей. Я не уверен, что это поможет мне, если только нет способа сообщить Java, какой сертификат в хранилище ключей использовать.

Ответы [ 2 ]

12 голосов
/ 20 мая 2009

SSL может предоставить клиенту подсказки о том, какой сертификат предоставить. Это может позволить вам использовать одно хранилище ключей с несколькими идентификаторами в нем, но, к сожалению, большинство серверов не используют эту функцию хинтинга. Таким образом, это будет более надежным, если вы укажете сертификат клиента, который будет использоваться для каждого соединения.

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

Инициализируйте контексты, которые вам понадобятся один раз, и повторно используйте правильный для каждого соединения. Если вы делаете несколько подключений, это позволит вам использовать сеансы SSL.

KeyManagerFactory kmf = 
  KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(identityStore, password);
TrustManagerFactory tmf =
  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

Позже вы можете создать сокет напрямую:

SSLSocketFactory factory = ctx.getSocketFactory();
Socket socket = factory.createSocket(host, port);

Или, если вы используете класс URL, вы можете указать SSLSocketFactory для использования при выполнении запросов HTTPS:

HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setSSLSocketFactory(ctx.getSocketFactory());

Java 6 имеет некоторый дополнительный API, который упрощает настройку сокетов в соответствии с вашими предпочтениями для комплектов шифров и т. Д.

0 голосов
/ 03 ноября 2009

Существует решение здесь для динамического выбора сертификата клиента, используемого для аутентификации SSL, от клиента Axis.

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