Java HttpsURLConnection和TLS 1.2

31

我在一篇文章中读到,HttpsURLConnection会自动协商SSL连接。

官方文档说:

该类使用HostnameVerifier和SSLSocketFactory。对于这两个类都定义了默认实现。[1]

这是否意味着一旦您打开了一个连接

httpsCon = (HttpsURLConnection) url.openConnection();

它已经使用SSL/TLS加密,无需再进行任何麻烦操作。

我如何查看和设置标准实现的TLS版本? (对于Java 8应该是TLS 1.2,对于Java 7应该是TLS 1.0)

参考资料

  1. Oracle Corp. (2011). javax.net.ssl.HttpsURLConnection.(JavaDoc)

2
请不要引用任意的互联网垃圾。除非您正在使用特定的JRE,而您没有说明,否则您引用的页面的正确URL为Oracle网站上的 - user207421
1
我添加了官方文件,而不是修改过的文件——非官方文件指出SSL是透明加密的,而官方文件则指出有默认实现。所以我的问题仍然是一样的,希望我的帖子现在更加清晰明了。 - Marc Wittmann
4
您可以通过设置 https.protocols 系统属性来指定要使用的 TLS 版本,请参见 这个答案 - vanOekel
我正在尝试在Java 1.6中使用以下方法:https://dev59.com/9JDea4cB1Zd3GeqPf8Bl - Azimuts
默认的连接模式是 SSL、TLS1.0 还是 TLS1.2? - Paritosh Agrawal
根据JDK 1.7中的Java版本,它将设置为TLS 1.0。 - Marc Wittmann
4个回答

36

Java 1.8中,您将需要创建一个SSLContext来设置协议:

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

Java 1.7中:

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

接下来,您只需将SSLContext设置为HttpsURLConnection

httpsCon.setSSLSocketFactory(sc.getSocketFactory());

那应该就可以了。


22
什么是 "trustCerts",如何创建/获取它? "trustCerts" 是一种用于建立和管理SSL/TLS连接的证书。您可以通过以下几种方式来创建或获取 "trustCerts" :
  1. 自签名证书:通过使用 OpenSSL 等工具生成自签名证书,并将其导入到 "trustCerts" 中。
  2. 从受信任的证书颁发机构(CA)获取证书:从已知的受信任 CA 获取证书并将其导入到 "trustCerts" 中。
  3. 动态生成证书:有些情况下,您可能需要动态生成证书以满足特定的需求。在这种情况下,您可以使用 Java 的 KeyStore API 来动态生成证书并将其添加到 "trustCerts" 中。
无论哪种方式,一旦您拥有了 "trustCerts",就可以在 SSL/TLS 连接中使用它来验证远程服务器的身份和建立安全连接。
- vianna77
2
如果有人对init()参数有疑问,这里是文档的说明:“前两个参数中的任一个都可以为null,在这种情况下,已安装的安全提供程序将被搜索以查找适当工厂的最高优先级实现。同样,如果安全随机参数为空,则使用默认实现。” - Danation
2
请参见 https://dev59.com/CnM_5IYBdhLWcg3w2XFg,其中提供了一个简单、不安全、信任所有证书的实现方式——trustCerts。 - Erich Kitzmueller

12
您可以在JDK 1.7中设置TLS1.2协议。默认情况下,JDK 1.7将其设置为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());

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

以上代码可用于在Java 1.7中启用TLS 1.1或TLS 1.2。


是的,它可能可以...但它能做什么呢? - foo
1
这可以帮助在Java 7中设置TLS 1.2,因为在Java 7中默认情况下未启用。 - Rahul
默认使用 SSL、TLS1.0 还是 TLS1.2? - Paritosh Agrawal

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

我尝试了这段代码,输出结果是"[TLSv1, TLSv1.1, TLSv1.2]",这应该意味着它支持"TLSv1, TLSv1.1, TLSv1.2"。但我不确定如何在HttpsUrlConnection中设置仅支持TLSv1.2。


1
(0)这不是一个答案,而StackExchange旨在将问题放在标记为问题的部分中,将答案放在标记为答案的部分中。(1)这将为您直接使用的“SSLSocket”设置协议和密码套件,并非为创建自己的套接字的“HttpsURLConnection”设置。(2)尽管您正式启用了1(.0),1.1,1.2,但您指定了适用于1.2的密码套件,因此,如果对等方同意1.2并且使用该密码套件,则获得1.2,否则会失败; 您永远不会获得1.1或1.0。 - dave_thompson_085

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接