Я хочу получить что-то вроде клиентских Compression_methods или наборов шифров, поддерживаемых клиентом, из рукопожатия ssl, которое я пытался использовать
public static void main(String[] args) throws Exception {
String serverKeyStoreFile = "D:\\tomcat.keystore";
String serverKeyStorePwd = "logiscn";
String catServerKeyPwd = "logiscn";
String serverTrustKeyStoreFile = "D:\\tomcat.keystore";
String serverTrustKeyStorePwd = "logiscn";
//System.setProperty("javax.net.debug", "ssl,handshake");
KeyStore serverKeyStore = KeyStore.getInstance("JKS");
serverKeyStore.load(new FileInputStream(serverKeyStoreFile), serverKeyStorePwd.toCharArray());
KeyStore serverTrustKeyStore = KeyStore.getInstance("JKS");
serverTrustKeyStore.load(new FileInputStream(serverTrustKeyStoreFile), serverTrustKeyStorePwd.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(serverKeyStore, catServerKeyPwd.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(serverTrustKeyStore);
SSLContext sslContext = SSLContext.getInstance("TLSv1");
// System.out.println(sslContext.getProvider());
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(SERVER_PORT);
// sslServerSocket.setNeedClientAuth(true);
while (true) {
SSLSocket s = (SSLSocket) sslServerSocket.accept();
// System.out.println(s);
//System.out.println(s.getClass());
// s.getSupportedProtocols()
CatServer cs = new CatServer(s);
//s.addHandshakeCompletedListener(cs);
s.startHandshake();
// System.out.println(s.getHandshakeSession().getProtocol());
new Thread(cs).start();
}
}
Но SSLSocket не содержит API для получения такой информации. Я прочитал исходный код о jsse.jar и обнаружил, что во время sslhandshake SSLSocket использует sun.security.ssl.ServerHandshaker для завершения всей обработки, а ServerHandshaker обновил ClientHello для восстановления этого.
void processMessage(byte paramByte, int paramInt) throws IOException {
if ((this.state >= paramByte) && (this.state != 16) && (paramByte != 15)) {
throw new SSLProtocolException("Handshake message sequence violation, state = " + this.state + ", type = " + paramByte);
}
switch (paramByte) {
case 1:
HandshakeMessage.ClientHello localClientHello = new HandshakeMessage.ClientHello(this.input, paramInt);
clientHello(localClientHello);
break;
case 11:
if (this.doClientAuth == 0) {
fatalSE((byte) 10, "client sent unsolicited cert chain");
}
clientCertificate(new HandshakeMessage.CertificateMsg(this.input));
break;
case 16:
SecretKey localSecretKey;
switch (this.keyExchange) {
case K_RSA:
case K_RSA_EXPORT:
RSAClientKeyExchange localRSAClientKeyExchange = new RSAClientKeyExchange(this.protocolVersion, this.clientRequestedVersion,
this.sslContext.getSecureRandom(), this.input, paramInt, this.privateKey);
localSecretKey = clientKeyExchange(localRSAClientKeyExchange);
break;
case K_KRB5:
case K_KRB5_EXPORT:
localSecretKey = clientKeyExchange(new KerberosClientKeyExchange(this.protocolVersion, this.clientRequestedVersion,
this.sslContext
.getSecureRandom(),
this.input,
getAccSE(), this.serviceCreds));
break;
case K_DHE_RSA:
case K_DHE_DSS:
case K_DH_ANON:
localSecretKey = clientKeyExchange(new DHClientKeyExchange(this.input));
break;
case K_ECDH_RSA:
case K_ECDH_ECDSA:
case K_ECDHE_RSA:
case K_ECDHE_ECDSA:
case K_ECDH_ANON:
localSecretKey = clientKeyExchange(new ECDHClientKeyExchange(this.input));
break;
default:
throw new SSLProtocolException("Unrecognized key exchange: " + this.keyExchange);
}
calculateKeys(localSecretKey, this.clientRequestedVersion);
break;
case 15:
clientCertificateVerify(new HandshakeMessage.CertificateVerify(this.input, getLocalSupportedSignAlgs(), this.protocolVersion));
break;
case 20:
if (!receivedChangeCipherSpec()) {
fatalSE((byte) 40, "Received Finished message before ChangeCipherSpec");
}
clientFinished(new HandshakeMessage.Finished(this.protocolVersion, this.input, this.cipherSuite));
break;
default:
throw new SSLProtocolException("Illegal server handshake msg, " + paramByte);
}
if (this.state < paramByte) {
if (paramByte == 15) {
this.state = (paramByte + 2);
} else {
this.state = paramByte;
}
}
}
проблема в том, что я не могу получить HandshakeMessage.ClientHello из объекта sslsocket.
SSLSession
, после согласования JSSE. Как вы думаете, зачем вам нужно знать наборы шифров, поддерживаемые клиентом? - person user207421   schedule 02.01.2018