我有一个运行了一段时间的客户端服务器应用程序。
尝试从客户端连接时,突然出现以下错误。我在服务器端没有看到错误。证书没有过期,我没有进行任何代码更改。在Google搜索此错误时,没有看到任何结果。
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);
}
答案 0 :(得分:0)
解决方案是遵循David的评论。
sC.setEnabledProtocols(new String[]{"TLSv1.2"});