6

When I execute the following code, why is the first handshake SSLv2, not TLSv1 or SSLv3?

How to use TLSV1 or SSLV3 for first handshake in Java?

String host = "www.google.com";
String url = "/adsense/?sourceid=aso&subid=ZH_CN-ET-AS-ADSBY6&medium=link&hl=zh_CN";
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
SSLContext.setDefault(ctx);
SSLSocketFactory factory = ctx.getSocketFactory();
Socket socket = factory.createSocket(host, 443);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write("GET " + url + " HTTP/1.0");
out.flush();
out.close();
in.close();
leppie
  • 115,091
  • 17
  • 196
  • 297
Steve
  • 281
  • 1
  • 3
  • 14
  • Check https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https – user454322 Oct 23 '14 at 06:58
  • Note that [it wasn't really an SSLv2 anyway](http://stackoverflow.com/a/4686924/372643), just an SSLv3 (or above) encapsulated into an SSLv2. – Bruno Dec 01 '14 at 10:30

3 Answers3

17

For TLSv1: Starting the client jvm with

-Dhttps.protocols="TLSv1" 

or using

System.setProperty("https.protocols", "TLSv1");

solved the problem for me.

shampoo
  • 190
  • 1
  • 10
  • The '-Dhttps.protocols' argument worked really well for me on some old, proprietary, black box software that I couldn't change. – Tom Purl Dec 16 '15 at 17:21
8

Use SSLSocket:

SSLSocket socket = factory.createSocket(host, 443);
String[] newProtocols = {"TLSv1"};
socket.setEnabledProtocols(newProtocols);
DarthJDG
  • 16,511
  • 11
  • 49
  • 56
Steve
  • 281
  • 1
  • 3
  • 14
0

Which version of java are you using? Also how do you say it uses SSLv2? By default, java 1.6 will use TLSv1. There is a catch here, if you enable debug ssl, you might see SSLv2Hello format being used but if you close look the 'protocol vesion' inside the record layer will be TLSv1 (1.e version information wrapper under SSLv2 format). TCP level packet capture analysis using wireshark should confirm this. If you want to initiate in TLSv1 format only set https.protocols=TLSv1 (this might affect all the outgoing ssl calls) OR set on that specific socket like above. Do note that even if you five comma separated list (like https.protocols=SSLv3,TLSv1) it will start with TLSv1.