How do I get a jersey client to use TLSv1.1? I’m trying to force a com.sun.jersey.client.urlconnection.HTTPSProperties (jersey client code eventually goes to this class) to use TLSv1.1 (or TLSv1) to write test code that confirms a server’s protocols. As I setup the client, I do the following:
SSLContext context = SSLContext.getInstance("TLSv1.1"); context.init(null, trustAll, new SecureRandom()); HTTPSProperties props = new HTTPSProperties(hv, context); clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, props);
Inside HTTPSProperties (I downloaded the 1.x source so this may be wrong) I see:
public void setConnection(HttpsURLConnection connection) { if (hostnameVerifier != null) connection.setHostnameVerifier(hostnameVerifier); connection.setSSLSocketFactory(sslContext.getSocketFactory()); }
If I use SSLContext.getInstance("TLS");
instead, the code works fine. I’ve tried add System.setProperty("https.protocols", "TLSv1.1");
but it still doesn’t work. The code above gives the stack trace:
Caused by: javax.net.ssl.SSLException: Received fatal alert: protocol_version at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2020) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1127) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1580) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1508) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:352) at com.sun.jersey.client.urlconnection.URLConnectionClientHandler._invoke(URLConnectionClientHandler.java:240) at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:147) ... 22 more
My server (Jetty 9.4.41) thinks it is allowing TLSV1.1. When I dump the sslFactory I get:
I. 2021-09-29 16:37:59. [main] SSL context: Server@239105a8[provider=null,keyStore=file:***,trustStore=null] - STOPPED +> trustAll=false +> Protocol Selections | +> Enabled size=3 | | +> TLSv1.1 | | +> TLSv1.2 | | +> TLSv1.3 | +> Disabled size=3 | +> SSLv2Hello - ConfigExcluded:'SSLv2Hello', ConfigIncluded:NotSelected | +> SSLv3 - ConfigExcluded:'SSLv3', ConfigIncluded:NotSelected JVM:disabled | +> TLSv1 - ConfigExcluded:'TLSv1', ConfigIncluded:NotSelected JVM:disabled +> Cipher Suite Selections +> Enabled size=39 | +> TLS_AES_128_GCM_SHA256 | +> TLS_AES_256_GCM_SHA384 | +> TLS_DHE_DSS_WITH_AES_128_CBC_SHA | +> TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 | +> TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 | +> TLS_DHE_DSS_WITH_AES_256_CBC_SHA | +> TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 | +> TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 | +> TLS_DHE_RSA_WITH_AES_128_CBC_SHA | +> TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 | +> TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 | +> TLS_DHE_RSA_WITH_AES_256_CBC_SHA | +> TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 | +> TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 | +> TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA | +> TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 | +> TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | +> TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA | +> TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 | +> TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 | +> TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA | +> TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 | +> TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | +> TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA | +> TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 | +> TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | +> TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA | +> TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 | +> TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 | +> TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA | +> TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 | +> TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 | +> TLS_ECDH_RSA_WITH_AES_128_CBC_SHA | +> TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 | +> TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 | +> TLS_ECDH_RSA_WITH_AES_256_CBC_SHA | +> TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 | +> TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 | +> TLS_EMPTY_RENEGOTIATION_INFO_SCSV +> Disabled size=6 +> TLS_RSA_WITH_AES_128_CBC_SHA - ConfigExcluded:'^TLS_RSA_.*$' +> TLS_RSA_WITH_AES_128_CBC_SHA256 - ConfigExcluded:'^TLS_RSA_.*$' +> TLS_RSA_WITH_AES_128_GCM_SHA256 - ConfigExcluded:'^TLS_RSA_.*$' +> TLS_RSA_WITH_AES_256_CBC_SHA - ConfigExcluded:'^TLS_RSA_.*$' +> TLS_RSA_WITH_AES_256_CBC_SHA256 - ConfigExcluded:'^TLS_RSA_.*$' +> TLS_RSA_WITH_AES_256_GCM_SHA384 - ConfigExcluded:'^TLS_RSA_.*$'
Any help is appreciated! Thanks in advance.
Advertisement
Answer
I simplified the question to how do I force a client to use TLSv1.1
I gave up using the jersey client and just used HttpsURLConnection. Turns out using the System.setProperties wasn’t a good ideal but the Diagnostics link from Tasos P. gave me ViewMyClient from SSL Labs.
Code below results in a report that SSL 3, TLS 1.0, and 1.1 are available but TLS 1.2, 1.3 and SSL 2 are not.
// Using these breaks things! //System.setProperty( "https.protocols", "TLSv1,TLSv1.1" ); //System.setProperty( "jdk.tls.disabledAlgorithms", "SSLv2Hello,SSLv3,TLSv1" ); String requestedProtocol = "TLSv1.1"; testOutput.reportHeader( "SSLLabs " + requestedProtocol ); SSLContext cx = SSLContext.getInstance( requestedProtocol ); cx.init( null, trustAll, new SecureRandom() ); testOutput.report( "Protocol: " + cx.getProtocol() ); testOutput.report( "Provider: " + cx.getProvider().toString() ); StringBuilder sb = new StringBuilder(); javax.net.ssl.SSLParameters p = cx.getSupportedSSLParameters(); sb.append( "Protocols={" ); for( String s : p.getProtocols() ) { sb.append( s ).append( ',' ); } sb.append( '}' ); testOutput.report( "SupportedSSLParameters: " + sb.toString() ); testOutput.report( "" ); int read; byte[] bytes = new byte[1024]; final URL url = new URL( "https://clienttest.ssllabs.com:8443/ssltest/viewMyClient.html" ); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory( cx.getSocketFactory() ); conn.setHostnameVerifier( hv ); try { testOutput.report( "Response Message: " + conn.getResponseMessage() ); InputStream in = conn.getInputStream(); File file = new File( filename ); FileOutputStream outputStream = new FileOutputStream( file ); while( (read = in.read(bytes)) != -1 ) { outputStream.write( bytes, 0, read ); } outputStream.close(); in.close(); testOutput.report( "File " + filename + " written." ); } catch( Exception ex ) { testOutput.reportException( ex ); }