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, который упрощает настройку сокетов в соответствии с вашими предпочтениями для комплектов шифров и т. Д.