简体   繁体   English

Java SSL:客户端握手失败和服务器没有共同的密码套件

[英]Java SSL: client handshake failure and server no cipher suites in common

I am trying to connect from client to server by SSL Socket in Java.我正在尝试通过 Java 中的 SSL 套接字从客户端连接到服务器。 Receiving handshake_failure on client side and no cipher suites in common on server side(www).在客户端接收handshake_failure,在服务器端(www)没有共同的密码套件。

Server is configured for SSL Tomcat 9, here is connector:服务器配置为 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" />

Client is Java project.客户为 Java 项目。 Both sides have certs in keytool.双方在keytool中都有证书。 Cert has been exported from keytool and imported at client side by keytool.证书已从 keytool 导出,并由 keytool 在客户端导入。 So, on client side and server side we have imported server.cer.因此,在客户端和服务器端,我们导入了 server.cer。 Tomcat starts on port 8443, sockets use port 443. Tomcat 从端口 8443 开始,sockets 使用端口 443。

What I have try?我有什么尝试? -setting protocols in code -setting cipher suites -changing ports -starting tomcat from 8080 and 8443 port - 在代码中设置协议 - 设置密码套件 - 更改端口 - 从 8080 和 8443 端口开始 tomcat

Server:服务器:

    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);
        }
    }

Client:客户:

    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());
        }

    }

Client error:客户端错误:

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)

Server(error is from web - JSP page):服务器(错误来自 web - 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.

Error says that there is no cipher suites, but I checked supported ciphers and choose one, available for both side.错误说没有密码套件,但我检查了支持的密码并选择了一个,双方都可用。 Declared TSL protocol and still no success.声明了 TSL 协议,但仍然没有成功。

I would like to connect from client to serversuccesfull, but have no idea what can I do next, due no advice found in internet.我想从客户端连接到服务器成功,但不知道下一步我能做什么,因为在互联网上找不到任何建议。

I had read something about private key required to do connection.我已经阅读了一些关于进行连接所需的私钥的内容。 Where is it?它在哪里? I assume, that server.cer have only public key.我假设 server.cer 只有公钥。

Is it proper to use port 443 for sockets, when tomcat runs on 8443?当 tomcat 在 8443 上运行时,为 sockets 使用端口 443 是否合适? Maybe I should specify those ports somewhere?也许我应该在某处指定这些端口?

One part of your question is about "certs", which - I assume - stands for a certificate.您的问题的一部分是关于“证书”,我假设它代表证书。

You are right, a certificate only contains a public key, which is signed by a certification authority (CA).你是对的,证书只包含一个由证书颁发机构 (CA) 签名的公钥。 The public key is only the public part of the assymetric key pair (eg RSA).公钥只是非对称密钥对(例如 RSA)的公共部分。 The server needs to have the private key.服务器需要有私钥。 Otherwise it cannot decrypt content which was encrypted with the public key, nor it can sign content sent to the client.否则它不能解密用公钥加密的内容,也不能对发送给客户端的内容进行签名。

This said, you need to create a RSA key pair, and make it available to tomcat.也就是说,您需要创建一个 RSA 密钥对,并将其提供给 tomcat。 Either you let it sign by a well known CA (makes a certificate), or you produce a self singned certificate by using key tool.要么让它由知名 CA 签名(制作证书),要么使用密钥工具生成自签名证书。 In the first case there is no special action needed on client side, because java (or browsers) know already the well known CA's public keys which are needed to verify the certificate which is delivered by your server.在第一种情况下,客户端不需要特殊操作,因为 java(或浏览器)已经知道众所周知的 CA 的公钥,这些公钥是验证服务器提供的证书所需的。 In case of a self signed certificate you have to import it at client side as a trusted one.如果是自签名证书,您必须在客户端将其作为受信任的证书导入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM