2009-05-20 3 views
6

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

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

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

ответ

11

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 запросы:

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

+0

«Java 6 имеет дополнительный API, который упрощает настройку сокетов в соответствии с вашими предпочтениями для наборов шифров» Можете ли вы указать мне дальнейшую документацию/обсуждение этих конфигураций? – Tazzy531

+0

@ Tazzy531 - Java 6 добавлена ​​['SSLParameters',] (http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/javax/net/ssl/class-use/SSLParameters. html), которую вы можете установить на «SSLEngine» или новом «SSLSocket» за одну операцию. – erickson

0

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