代码之家  ›  专栏  ›  技术社区  ›  KisnardOnline

Java客户端连接错误:CuxECiFSPEC消息序列违例

  •  5
  • KisnardOnline  · 技术社区  · 7 年前

    我有一个客户机-服务器应用程序已经运行了一段时间了。
    当我试图从客户机连接时,突然出现了以下错误。我在服务器端看不到任何错误。证书没有过期,我没有更改代码。在谷歌搜索这个错误时,我没有看到任何结果。

    javax.net.ssl.SSLProtocolException: ChangeCipherSpec message sequence violation
        at sun.security.ssl.HandshakeStateManager.changeCipherSpec(Unknown Source)
        at sun.security.ssl.Handshaker.receiveChangeCipherSpec(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
        at sun.security.ssl.AppInputStream.read(Unknown Source)
        at sun.security.ssl.AppInputStream.read(Unknown Source)
        at java.io.DataInputStream.readUnsignedShort(Unknown Source)
        at java.io.DataInputStream.readUTF(Unknown Source)
        at java.io.DataInputStream.readUTF(Unknown Source)
        at com.jayavon.game.client.cj.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
    

    客户端代码:

    //load your key store as a stream and initialize a KeyStore
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());    
    
    //if your store is password protected then declare it (it can be null however)
    String tsName = "res/gamedata/truststore";
    char[] trustPassword = "--REMOVED--".toCharArray();
    
    //load the stream to your store
    trustStore.load(new FileInputStream(tsName), trustPassword);
    
    //initialize a trust manager factory with the trusted store
    TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());    
    trustFactory.init(trustStore);
    
    //get the trust managers from the factory
    TrustManager[] trustManagers = trustFactory.getTrustManagers();
    
    //initialize an ssl context to use these managers and set as default
    SSLContext sslContext = SSLContext.getInstance("SSL");
    sslContext.init(null, trustManagers, null);
    SSLContext.setDefault(sslContext);
    
    //create sslfactory from the ssl context
    SSLSocketFactory factory = sslContext.getSocketFactory();
    
    if (isPROD){
        sC = (SSLSocket) factory.createSocket("--REMOVED--", --REMOVED--);
    } else {
        sC = (SSLSocket) factory.createSocket("localhost", --REMOVED--);
    }
    
    sC.addHandshakeCompletedListener(new HandshakeCompletedListener(){
        @Override
        public void handshakeCompleted(HandshakeCompletedEvent arg0) {
            logger.info("------HANDSHAKE START------");
            logger.info("Cipher suite: " + arg0.getCipherSuite());
    
            logger.info("Local Principal: " + arg0.getLocalPrincipal());
    
            X509Certificate[] peerCertChain = null;
            try {
                peerCertChain = arg0.getPeerCertificateChain();
            } catch (SSLPeerUnverifiedException e1) {
                logger.error("arg0.getPeerCertificateChain()", e1);
            }
            for (X509Certificate s: peerCertChain){
                logger.info("Local Certificate(SigAlgName): " + s.getSigAlgName());
                logger.info("Local Certificate(SigAlgOID): " + s.getSigAlgOID());
                logger.info("Local Certificate(Version): " + s.getVersion());
                logger.info("Local Certificate(IssuerDN): " + s.getIssuerDN());
                logger.info("Local Certificate(NotAfter): " + s.getNotAfter());
                logger.info("Local Certificate(NotBefore): " + s.getNotBefore());
                logger.info("Local Certificate(PublicKey): " + s.getPublicKey());
                logger.info("Local Certificate(SerialNumber): " + s.getSerialNumber());
                logger.info("Local Certificate(SubjectDN): " + s.getSubjectDN());
            }
    
            Certificate[] peerCertificates = null;
            try {
                peerCertificates = arg0.getPeerCertificates();
            } catch (SSLPeerUnverifiedException e) {
                logger.error("arg0.getPeerCertificates()", e);
            }
            for (Certificate s: peerCertificates){
                logger.info("Peer Certificate(public key): " + s.getPublicKey());
            }
    
            try {
                logger.info("Peer Principal: " + arg0.getPeerPrincipal());
            } catch (SSLPeerUnverifiedException e) {
                logger.error("arg0.getPeerPrincipal()", e);
            }
            logger.info("Session: " + arg0.getSession());
            logger.info("Socket: " + arg0.getSocket());
            logger.info("Source: " + arg0.getSource());
            logger.info("------HANDSHAKE DONE------");
        }
    });
    
    sC.startHandshake();
    

    服务器代码:

    String ksName = "res/gamedata/server.keystore";
    char ksPass[] = "--REMOVED--".toCharArray();
    
    //create new keystore instance
    KeyStore ks = KeyStore.getInstance("JKS");
    
    //load the keystore with password into the keystore
    ks.load(new FileInputStream(ksName), ksPass);
    
    //create a new keymanagerfactory and initalize with the keystore
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, ksPass);
    
    //initialize an ssl context with TLS with the keymanagers(server certificate/decrypted private key)
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(kmf.getKeyManagers(), null, null);
    
    //create sslfactory from the ssl context
    SSLServerSocketFactory ssf = sc.getServerSocketFactory();
    
    //create the server socket for clients to connect to
    s = (SSLServerSocket) ssf.createServerSocket(--REMOVED--);
    
    sC = (SSLSocket) s.accept();
    
    sC.addHandshakeCompletedListener(new HandshakeCompletedListener(){
        @Override
        public void handshakeCompleted(HandshakeCompletedEvent arg0) {
            LOGGER.info("------HANDSHAKE START------");
            LOGGER.info("Cipher suite: " + arg0.getCipherSuite());
    
            Certificate[] localCerts = arg0.getLocalCertificates();
            for (Certificate s: localCerts){
                LOGGER.info("Local Certificate(public key): " + s.getPublicKey());
            }
    
            LOGGER.info("Local Principal: " + arg0.getLocalPrincipal());
    
            LOGGER.info("Session: " + arg0.getSession());
            LOGGER.info("Socket: " + arg0.getSocket());
            LOGGER.info("Source: " + arg0.getSource());
            LOGGER.info("------HANDSHAKE DONE------");
        }
    });
    
    try {
        sC.startHandshake();
    } catch (SSLHandshakeException e2){
        LOGGER.error("client handshake issue for IP(" + sC.getLocalAddress().toString() + ")", e2);
    }
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   KisnardOnline    7 年前

    解决办法是遵循大卫的评论。

    sC.setEnabledProtocols(new String[]{"TLSv1.2"});