Java: как добавить SSL-аутентификацию на стороне клиента
У меня есть этот код для подключения сервера к клиенту с использованием SSL, и теперь я хочу добавить проверку на стороне клиента:
(У меня есть серверное хранилище ключей (тип JCEKS) и клиентское хранилище ключей (тип JKS), сервер использует truststore (cacerts), где я импортировал оба сертификата, потому что я также хочу использовать этот доверенный сервер для проверки подлинности клиента)
Клиентский код:
System.setProperty("javax.net.ssl.trustStore", cerServer);
System.setProperty("javax.net.ssl.trustStoreType","JCEKS");
System.setProperty("javax.net.ssl.trustStorePassword", pwdCacerts);
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost", port);
Код сервера:
KeyStore ks = LoadKeyStore(new File(serverKeyStore), pwdKeyStore, "JCEKS");
KeyManagerFactory kmf;
kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, pwdKeyStore.toCharArray());
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(kmf.getKeyManagers(),null, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
sslserversocket = (SSLServerSocket) ssf.createServerSocket(port);
заблаговременно за помощь.
изменить:
Я добавляю этот код на стороне сервера:
System.setProperty("javax.net.ssl.trustStore", cacerts);
System.setProperty("javax.net.ssl.trustStoreType","JKS");
System.setProperty("javax.net.ssl.trustStorePassword", pwdCacerts);
но если я удалю сертификат клиента в cacerts, соединение не даст мне ошибку и для этого я считаю, что это неправильно.
Ответы
Ответ 1
Если вы хотите, чтобы ваша система использовала аутентификацию сертификата клиента, вам понадобится
-
сервер запрашивает (или требует) клиентский сертификат. Это делается установкой setWantClientAuth(true)
на сокет сервера (или setNeedClientAuth
, соответственно). Вам также понадобится сервер для рекламы CA, который он принимает, что обычно делается с помощью доверительного хранилища на сервере, который содержит CA, с помощью которого была создана цепочка клиент-сертификат (это, по-видимому, было тем, что вы сделали, установив javax.net.ssl.trustStore*
на сервере).
-
клиент должен быть настроен с хранилищем ключей, содержащим клиентский сертификат (возможно, цепочка, если есть промежуточные ЦС) и его закрытый ключ. Это можно сделать, установив javax.net.ssl.keyStore*
(что может повлиять на другие подключения) или с помощью KeyManagerFactory
так же, как вы сделали это на стороне сервера.
Если вы используете setWantClientAuth(true)
, вы все равно не получите ошибку, так как сервер будет принимать соединения, у которых нет клиентского сертификата (сервер затем проверит сертификаты peer SSLSession
, чтобы узнать, есть ли сертификат или нет). setNeedClientAuth(true)
нарушит соединение, если клиент не предоставит сертификат.