Я хотел бы знать, как я могу реализовать сокет сервера, чтобы он мог идентифицировать и использовать
правильный сертификат в соответствии с сертификатом, используемым клиентом для продолжения
рукопожатие связи с сервером.
Объясняя лучше, на стороне сервера:
AppServerSideSocket.jar
- хранилище личных ключей: privateKeyApp (тип JKS, сгенерированный с помощью keytool)
- хранилище открытых ключей: publicKeyApp (тип JKS, общий для всех клиентов)
А на стороне клиента ...
AppClientSideSocket.jar
- хранилище открытых ключей: publicKeyApp
AppServerSideSocket.jar прослушивание запросов клиентов и однажды полученный процесс
информация, отправленная клиентами
AppClientSideSocket.jar соединяется с сервером по протоколу SSL с использованием publicKeyApp без
проверьте имя хоста сервера и после рукопожатия отправьте информацию для приложения AppServerSideSocket.
Теперь у меня есть другое клиентское приложение, AppClientSideSocketNEW.jar , и это проверяет имя хоста сервера для
связь с сервером. В этом случае CN используется в публичном сертификате на стороне клиента
должен совпадать с именем хоста, где AppServerSideSocket.jar .
Первоначально соединение было настроено таким образом на стороне сервера:
if (usingSSLConn) {
System.setProperty("javax.net.ssl.keyStore", "privateKeyApp");
System.setProperty("javax.net.ssl.keyStorePassword", "privateKeyAppPassword");
SSLServerSocketFactory sslServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ServerSocket serverSocketApp = sslServerSocketFactory.createServerSocket(Port);
} else
serverSocketApp = new ServerSocket(Port);
}
Все клиенты получили одно и то же publicKeyApp и подключаются к серверу без проверки имени хоста, поэтому не имеет значения
если сервер, на котором установлено приложение сокета сервера ( AppServerSideSocket.jar ) на сервере с именем хоста,
badServer1.com и CN ключа в privateKeyApp и publicKeyApp установлены с goodServer1.com, потому что все клиенты не проверяют имя хоста или атрибут CN ключа.
Ниже показан кусок этого вида соединения:
private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
System.setProperty("javax.net.ssl.trustStore", publicKey1);
System.getProperties().setProperty("java.protocol.handler.pkgs",
"javax.net.ssl.internal.www.protocol");
HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);
...
SOAPConnectionFactory soapConn = SOAPConnectionFactory.newInstance();
SOAPConnection connection = soapConn.createConnection();
...
URL endpoint = new URL(hostname + ":" + port);
Но новый клиент ( AppClientSideSocketNEW.jar ) выполняет эту проверку принудительно, теперь необходимо предоставить новый сертификат
для этого клиента с новым значением для атрибута CN, отражающего правильное имя хоста CN, где сокет сервера.
У меня нет доступа ко второму клиенту, и я уверен, что он выполняет проверку имени хоста.
Итак, я создал два новых сертификата пары ключей ( privateKeyAppNew и publicKeyAppNew ), и, очевидно, связь произошла
с успехом между сервером, использующим эту новую пару ключей, и новым клиентом, использующим этот новый открытый ключ publicKeyAppNew.
Но мне нужно продолжать использовать старую пару ключей для старых клиентов. Я хотел бы знать, как я могу справиться с этим.
Использование диспетчера ключей позволяет мне проверять сертификат клиента в приложении сервера, когда клиент пытается подключиться, и
выбрать подходящий и сделать рукопожатие, используя правильный сертификат?
Или мне нужно различное соединение через ssl-сокет в разных портах для какого типа клиентов?