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); } }