31

I read in an article that HttpsURLConnection will transparently negotiate the SSL connection.

The official document says:

This class uses HostnameVerifier and SSLSocketFactory. There are default implementations defined for both classes. [1]

Does that mean once you open a connection with

httpsCon = (HttpsURLConnection) url.openConnection();

It is already SSL/TLS encrypted without any more hassle?

How can I view and set the TLS version for the standard implementation? (Should be TLS 1.2 for Java 8 and TLS 1.0 for Java 7)

References

  1. Oracle Corp. (2011). javax.net.ssl.HttpsURLConnection. (JavaDoc)
javabrett
  • 7,020
  • 4
  • 51
  • 73
Marc Wittmann
  • 2,286
  • 2
  • 28
  • 41
  • 2
    Please don't cite arbitrary Internet junk. Unless you're using that specific JRE, which you don't state, the correct URL for the page you cited is [at the Oracle website](https://docs.oracle.com/javase/8/docs/api/javax/net/ssl/HttpsURLConnection.html). – user207421 May 08 '15 at 10:28
  • 1
    I added the official document instead of the altered one - the unoffial one states that SSL is transparently neotated, the official one states that there are default implementations. So my question is still the same, hope my post is now more transparent. – Marc Wittmann May 08 '15 at 11:50
  • 4
    You can set the TLS version to use via the `https.protocols` system property, see [this answer](http://serverfault.com/a/660698). – vanOekel May 08 '15 at 13:11
  • I'm trying this way in **Java 1.6** : http://stackoverflow.com/questions/33517476/tls-1-2-java-1-6-bouncycastle – Azimuts Nov 04 '15 at 10:09
  • What is the default connection mode SSL, TLS1.0 or TLS1.2 ? – Paritosh Agrawal Jul 24 '20 at 04:33
  • Depends on the java version in JDK 1.7 it will set it to TLS 1.0 – Marc Wittmann Jul 25 '20 at 11:45

4 Answers4

36

You will have to create an SSLContext to set the Protocoll:

in Java 1.8:

 SSLContext sc = SSLContext.getInstance("TLSv1.2");
 // Init the SSLContext with a TrustManager[] and SecureRandom()
 sc.init(null, trustCerts, new java.security.SecureRandom()); 

in Java 1.7:

 SSLContext sc = SSLContext.getInstance("TLSv1");
 // Init the SSLContext with a TrustManager[] and SecureRandom()
 sc.init(null, trustCerts, new java.security.SecureRandom());

then you just have to set the SSLContext to the HttpsURLConnection:

httpsCon.setSSLSocketFactory(sc.getSocketFactory());

That should do the Trick.

JoCoaker
  • 633
  • 9
  • 18
  • 22
    What is **trustCerts** and how do you create/get one? – vianna77 Dec 23 '16 at 10:53
  • 2
    In case anybody was wondering about the init() parameters, here's what the documentation says: "Either of the first two parameters may be null in which case the installed security providers will be searched for the highest priority implementation of the appropriate factory. Likewise, the secure random parameter may be null in which case the default implementation will be used." – Danation Jun 12 '17 at 16:59
  • 2
    See https://stackoverflow.com/questions/1201048/allowing-java-to-use-an-untrusted-certificate-for-ssl-https-connection for a trivial, unsafe, all-trusting implementation of **trustCerts** – Erich Kitzmueller Feb 20 '18 at 14:59
12

You can also set TLS 1.2 protocol with the JDK 1.7. By default JDK 1.7 will set it to 1.0.

SSLContext sc = SSLContext.getInstance("TLSv1.2"); //$NON-NLS-1$
sc.init(null, null, new java.security.SecureRandom());
HttpsURLConnection con = (HttpsURLConnection) httpsURL.openConnection();
con.setSSLSocketFactory(sc.getSocketFactory());
Kondal Kolipaka
  • 3,471
  • 22
  • 28
0
private static javax.net.ssl.SSLSocketFactory getFactorySimple() 
        throws Exception {
    SSLContext context = SSLContext.getInstance("TLSv1.2");`

    context.init(null, null, null);

    return context.getSocketFactory();

}

String loginurl ="some url";
HttpsURLConnection connection = null;
URL url = new URL(loginURL);

connection = (HttpsURLConnection) url.openConnection();

javax.net.ssl.SSLSocketFactory sslSocketFactory =getFactorySimple();

connection.setSSLSocketFactory(sslSocketFactory);

The above code can be used to enable tls 1.1 or tls 1.2 in java 1.7

Bex
  • 2,905
  • 2
  • 33
  • 36
Rahul
  • 11
  • 2
-1
    SSLContext sc = SSLContext.getInstance("TLSv1.2");
    sc.init(null,null,null);
    SSLSocketFactory sf = sc.getSocketFactory();
    SSLSocket ss = (SSLSocket)sf.createSocket();
    String[] pro = {"TLSv1.2"};
    String[] cipherSuites = {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"};
    //ss.setEnabledProtocols(pro);
    ss.setEnabledCipherSuites(cipherSuites);
    System.out.println(Arrays.toString(ss.getEnabledProtocols()));

I have tried this code, the output is "[TLSv1, TLSv1.1, TLSv1.2]", It should mean this supports "TLSv1, TLSv1.1, TLSv1.2". I'm confused that how to set to TLSv1.2 only with HttpsUrlConnection ?

Chao Guo
  • 1
  • 1
  • 1
    (0) this is not an answer, and StackExchange is designed to have questions in the section labelled question and answers in the section labelled answers. (1) This sets the protocols and ciphersuite for an `SSLSocket` you use directly, not for an `HttpsURLConnection` which creates its own socket. The 4-year-old correct answers address `HttpsURLConnection`. (2) Although you leave 1(.0),1.1,1.2 formally enabled, you specify a ciphersuite that only works in 1.2, so if the peer agrees to 1.2 _and_ that ciphersuite you get 1.2 and otherwise you get failure; you never get 1.1 or 1.0. – dave_thompson_085 Aug 04 '21 at 03:28