title: Java Client Connection Error: ChangeCipherSpec message sequence violation
body: <p>I have a client server application that has been running fine for awhile now.<br>
  Suddenly I am getting the below error when attempting to connect from the client.  I see no errors on the server side.  The certificates are not expired and I have made no code changes.  I do not see any results when searching Google for this error.</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>Client Code:</p>
  
  <pre><code>//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();
  </code></pre>
  
  <p>Server Code:</p>
  
  <pre><code>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);
  }
  </code></pre>