Через несколько клиентских сертификатов SSL в Java с одного узла
в моем Java-приложении мне нужно подключиться к одному хосту с помощью SSL, но каждый раз использовать другой сертификат. Причина, по которой мне нужно использовать разные сертификаты, заключается в том, что удаленный сайт использует свойство User ID, встроенное в сертификат для идентификации клиента.
это серверное приложение, которое работает на 3 разных операционных системах, и мне нужно иметь возможность переключать сертификаты без перезапуска процесса.
другой пользователь предложил импорт нескольких сертификатов в одно хранилище ключей. Я не уверен, что это помогает мне, хотя, если нет способа сказать Java, какой сертификат в хранилище ключей использовать.
2 ответов
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, который упрощает настройку сокетов в соответствии с вашими предпочтениями для наборов шифров и т. д.
выход есть здесь для динамического выбора сертификата клиента, используемого для аутентификации SSL от клиента Axis.