Подключение SSL-разъема
Как создать соединение с SSL-соединением?
Мне действительно нужно создать хранилище ключей? Это хранилище ключей должно быть доступно всем моим клиентским приложениям?
Я создал сервер со следующим кодом:
SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory
.getDefault();
SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory
.createServerSocket(ServerProperties.getInstance()
.getVSSPAuthenticationPort());
Я создаю клиент для android со следующим кодом:
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
host, authPort);
sslsocket.startHandshake();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
sslsocket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(
sslsocket.getInputStream()));
Но когда я пытаюсь подключиться, выдается следующая ошибка:
javax.net.ssl.SSLHandshakeException: no cipher suites in common
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:266)
at sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:894)
at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:622)
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:167)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
Ответы
Ответ 1
Вам нужен сертификат для установления соединения ssl, вы можете загрузить сертификат внутри хранилища ключей или загрузить сам сертификат. Я покажу несколько примеров для параметра хранилища ключей.
Вашему коду нужны некоторые параметры для запуска:
java -Djavax.net.ssl.keyStore=keyStoreFile -Djavax.net.ssl.keyStorePassword=keystorePassword Server
Вы также можете загрузить хранилище ключей с помощью java-кода, самым простым решением для этого является установка свойств системы:
System.setProperty("javax.net.ssl.keyStore", 'keystoreFile');
System.setProperty("javax.net.ssl.keyStorePassword", 'keystorePassword ');
Также вы можете загрузить хранилище ключей по-другому, его сложнее, но у вас есть возможность делать более сложные вещи:
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("keystoreFile"), "keystorePassword".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(ks, "keystorePassword".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(ks);
SSLContext sc = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
sc.init(kmf.getKeyManagers(), trustManagers, null);
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(serverport);
SSLSocket c = (SSLSocket) s.accept();
Для клиентов есть несколько изменений в последних строках кода, три последних строки будут заменены следующими:
SSLSocketFactory ssf = sc.getSocketFactory();
SSLSocket s = (SSLSocket) ssf.createSocket(serverip, serverport);
s.startHandshake();
Если вы хотите загрузить хранилище ключей для андроида, тип должен быть "BKS", а не "JKS". Вы можете легко найти ресурсы для создания хранилища ключей.