Я пытаюсь подключиться от клиента к серверу через сокет SSL в Java. Получение handshake_failure на стороне клиента и никаких общих наборов шифров на стороне сервера (www).
Сервер настроен для SSL Tomcat 9, здесь есть соединитель:
<Connector SSLEnabled="true" acceptCount="100" clientAuth="false"
disableUploadTimeout="true" enableLookups="false" maxThreads="25"
port="8443" keystoreFile="C:/Users/xxx/.keystore" keystorePass="xxx"
keystoreType="PKCS12"
protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="https"
secure="true" sslProtocol="TLS" />
Клиент - проект Java. Обе стороны имеют сертификаты в Keytool. Сертификат был экспортирован из keytool и импортирован на стороне клиента с помощью keytool. Итак, на стороне клиента и на стороне сервера мы импортировали server.cer. Tomcat запускается через порт 8443, сокеты используют порт 443.
Что я пробую? -установка протоколов в коде -установка наборов шифров -перемена портов -запуск tomcat с 8080 и 8443 порта
Сервер:
void mySSLServerSocket(int port) throws IOException {
SSLServerSocketFactory sslServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(port);
sslServerSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
sslServerSocket.setEnabledCipherSuites(new String[] {"TLS_RSA_WITH_AES_256_CBC_SHA"});
SSLSocket socket = (SSLSocket) sslServerSocket.accept();
OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();
while(true) {
int orderNumber = in.read();
System.out.println("order number readed: " + orderNumber);
}
}
Клиент:
void mySocket(String ip, int port) throws IOException {
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(ip, port);
sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
sslSocket.setEnabledCipherSuites( new String[] {"TLS_RSA_WITH_AES_256_CBC_SHA"});
sslSocket.startHandshake();
InputStream in = sslSocket.getInputStream();
OutputStream out = sslSocket.getOutputStream();
out.write(1);
while (in.available() > 0) {
System.out.print(in.read());
}
}
Ошибка клиента:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2020)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1127)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
at com.company.SocketUtil.mySocket(SocketUtil.java:31)
at com.company.Main.main(Main.java:15)
Сервер (ошибка с веб-страницы JSP):
Type Exception Report
Message no cipher suites in common
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.net.ssl.SSLHandshakeException: no cipher suites in common
java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)
java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:254)
java.base/sun.security.ssl.ServerHello$T12ServerHelloProducer.chooseCipherSuite(ServerHello.java:460)
java.base/sun.security.ssl.ServerHello$T12ServerHelloProducer.produce(ServerHello.java:295)
java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
java.base/sun.security.ssl.ClientHello$T12ClientHelloConsumer.consume(ClientHello.java:1102)
java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:854)
java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)
java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:177)
java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1180)
java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1091)
java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:721)
java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:804)
java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:763)
ServerSocketUtils.mySSLServerSocket(ServerSocketUtils.java:38)
MusicControl.doPost(MusicControl.java:24)
javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.
Ошибка говорит о том, что нет комплектов шифров, но я проверил поддерживаемые шифры и выбрал один, доступный дляобе стороны. Объявленный протокол TSL и до сих пор не увенчался успехом.
Я хотел бы подключиться от клиента к серверу успешно, но понятия не имею, что мне делать дальше, потому что в интернете нет советов.
Я прочиталчто-то о закрытом ключе требуется для подключения. Где это находится? Я предполагаю, что у server.cer есть только открытый ключ.
Правильно ли использовать порт 443 для сокетов, когда tomcat работает на 8443? Может мне где-то указать эти порты?