当我尝试将现有的Socket连接升级到SSLSocket连接并设置setUseClientMode(true)
时,我在调用javax.net.ssl.SSLProtocolException: Handshake message sequence violation, 1
时收到错误mySSLSocket.startHandshake();
。当没有设置setUseClientMode()
时,一切正常,我可以发送和接收消息。我不是要求修复,只是它意味着什么以及可能导致它的原因。
答案 0 :(得分:0)
确定此方(a)是发送还是(b)期望接收初始握手消息ClientHello
。如果useClientMode
为真,则此方发送。除非你真的知道自己在做什么,否则不要将它设置在服务器上。如果您在服务器中并且正在升级已接受的Socket
,那么必须将其设置为 false。否则,实际上很少有机会在所有
NB useClientMode=true
是默认设置。
答案 1 :(得分:-1)
setUseClientMode
与它说的并不多。该属性指定通信的哪一方管理sslsocket,check standard implementation。
SslSocket Server端的伪代码:
private ServerSocket createServerSocket(InetAddress localIp, int port) throws IOException {
ServerSocket sock;
Boolean dataProtection = (Boolean) ctx.getAttribute(FtpConstants.ATTR_DATA_PROT);
boolean ssl = dataProtection != null && dataProtection;
if (ssl) {
SSLServerSocketFactory factory = ctx.getOptions().getSslContext().getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket) factory.createServerSocket(port, 1, localIp);
sslServerSocket.setUseClientMode(false);
enableCipherSuites(sslServerSocket);
sock = sslServerSocket;
} else {
sock = ServerSocketFactory.getDefault().createServerSocket(port, 1, localIp);
}
sock.setSoTimeout(DATA_CHANNEL_TIMEOUT);
return sock;
}
伪客户端:
public void test_UseClientMode() throws Exception {
SSLServerSocket sss = getSSLServerSocket();
sss.setUseClientMode(false);
assertFalse(sss.getUseClientMode());
sss.setUseClientMode(true);
assertTrue(sss.getUseClientMode());
}
所以最后你的握手错误告诉你演员在握手解析期间有错误的消息类型:
if (state >= type
&& (type != HandshakeMessage.ht_hello_request)) {
throw new SSLProtocolException(
"Handshake message sequence violation, " + type);
}
其中ht_hello_request是开始通信中的第一条消息,它是来自当前actor的通信端的意外类型。