Java – extended server_ Name (SNI extension) is not jdk1 8.0, but jdk1.0 7.0 sent
I have implemented a jax-ws client using Apache CXF (v3.0.4) and everything works normally, but there is a problem when I want to use secure connection (SSL / TLS) and Java 8 (jdk1.8.0_25)
I see the following exception in the log (- djavax. Net. Debug = all):
main,handling exception: java.net.socketException: Connection reset main,SEND TLSv1.2 ALERT: fatal,description = unexpected_message main,WRITE: TLSv1.2 Alert,length = 2 main,Exception sending alert: java.net.socketException: Connection reset by peer: socket write error
After peer analysis, I observed that the problem was caused by using java 8 instead of sending the server name (SNI), but using java 7 to send the problem, and the web service call worked successfully
Java 8 log (- djavax. Net. Debug = all): missing "extension server_name"
[...]
Compression Methods: { 0 }
Extension elliptic_curves,curve names: {secp256r1,sect163k1,sect163r2,secp192r1,secp224r1,sect233k1,sect233r1,sect283k1,sect283r1,secp384r1,sect409k1,sect409r1,secp521r1,sect571k1,sect571r1,secp160k1,secp160r1,secp160r2,sect163r1,secp192k1,sect193r1,sect193r2,secp224k1,sect239k1,secp256k1}
Extension ec_point_formats,formats: [uncompressed]
Extension signature_algorithms,signature_algorithms: SHA512withECDSA,SHA512withRSA,SHA384withECDSA,SHA384withRSA,SHA256withECDSA,SHA256withRSA,SHA224withECDSA,SHA224withRSA,SHA1withECDSA,SHA1withRSA,SHA1withDSA,MD5withRSA
***
[...]
Java 7 log (- djavax. Net. Debug = all) (works): "extension server_name" is set
[...]
Compression Methods: { 0 }
Extension elliptic_curves,MD5withRSA
Extension server_name,server_name: [host_name: testeo.hostname.es]
***
[...]
It was observed that Java 7 was used with the extension server_ name,server_ Name: [host_name: testeo. Hostname. Es] is set, and then the web service call works successfully
Why does Java 7 not use server_ Set name to Java 7? Is it a Java configuration problem?
Solution
As mentioned above, the reason is related to the JDK error using sethostnameverifier() and SNI (extension server_name)
Our solution: after testing, we found that setting the connected sslsocketfactory to anything similar to the default value seems to solve the problem
This doesn't work: httpsurlconnection setSSLSocketFactory((SSLSocketFactory)SSLSocketFactory. getDefault());
This works: httpsurlconnection setSSLSocketFactory(new SSLSocketFactoryFacade());
So, to fix a jax-ws client, you can do this: bindprovider getRequestContext(). Put ("com. Sun. XML. Internal. WS. Transport. HTTPS. Client. Sslsocketfactory", new sslsocketfactoryfacade ());
Our sslsocketfactory facade: (note that it really doesn't do anything)
public class SSLSocketFactoryFacade extends SSLSocketFactory {
SSLSocketFactory sslsf;
public SSLSocketFactoryFacade() {
sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();;
}
@Override
public String[] getDefaultCipherSuites() {
return sslsf.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return sslsf.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket socket,String s,int i,boolean b) throws IOException {
return sslsf.createSocket(socket,s,i,b);
}
@Override
public Socket createSocket(String s,int i) throws IOException,UnkNownHostException {
return sslsf.createSocket(s,i);
}
@Override
public Socket createSocket(String s,InetAddress inetAddress,int i1) throws IOException,inetAddress,i1);
}
@Override
public Socket createSocket(InetAddress inetAddress,int i) throws IOException {
return createSocket(inetAddress,i);
}
@Override
public Socket createSocket(InetAddress inetAddress,InetAddress inetAddress1,int i1) throws IOException {
return createSocket(inetAddress,inetAddress1,i1);
}
}
