繁体   English   中英

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

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

我正在尝试通过 Java 中的 SSL 套接字从客户端连接到服务器。 在客户端接收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 开始,sockets 使用端口 443。

我有什么尝试? - 在代码中设置协议 - 设置密码套件 - 更改端口 - 从 8080 和 8443 端口开始 tomcat

服务器:

    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)

服务器(错误来自 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.

错误说没有密码套件,但我检查了支持的密码并选择了一个,双方都可用。 声明了 TSL 协议,但仍然没有成功。

我想从客户端连接到服务器成功,但不知道下一步我能做什么,因为在互联网上找不到任何建议。

我已经阅读了一些关于进行连接所需的私钥的内容。 它在哪里? 我假设 server.cer 只有公钥。

当 tomcat 在 8443 上运行时,为 sockets 使用端口 443 是否合适? 也许我应该在某处指定这些端口?

您的问题的一部分是关于“证书”,我假设它代表证书。

你是对的,证书只包含一个由证书颁发机构 (CA) 签名的公钥。 公钥只是非对称密钥对(例如 RSA)的公共部分。 服务器需要有私钥。 否则它不能解密用公钥加密的内容,也不能对发送给客户端的内容进行签名。

也就是说,您需要创建一个 RSA 密钥对,并将其提供给 tomcat。 要么让它由知名 CA 签名(制作证书),要么使用密钥工具生成自签名证书。 在第一种情况下,客户端不需要特殊操作,因为 java(或浏览器)已经知道众所周知的 CA 的公钥,这些公钥是验证服务器提供的证书所需的。 如果是自签名证书,您必须在客户端将其作为受信任的证书导入。

暂无
暂无

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

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