【问题标题】:Java HttpsURLConnection and TLS 1.2Java HttpsURLConnection 和 TLS 1.2
【发布时间】:2015-05-08 10:24:45
【问题描述】:

我在一篇文章中读到HttpsURLConnection 将透明地协商 SSL 连接。

官方文档说:

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

这是否意味着一旦您打开与

的连接
httpsCon = (HttpsURLConnection) url.openConnection();

它已经被 SSL/TLS 加密了,没有任何麻烦?

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

参考文献

  1. 甲骨文公司 (2011)。 javax.net.ssl.HttpsURLConnection。 (JavaDoc)

【问题讨论】:

  • 请不要随意引用互联网垃圾。除非您使用的是您未声明的特定 JRE,否则您引用的页面的正确 URL 是 at the Oracle website
  • 我添加了官方文档而不是更改的文档 - 非官方文档声明 SSL 是透明的新版本,官方文档声明有默认实现。所以我的问题还是一样,希望我的帖子现在更加透明。
  • 您可以通过https.protocols系统属性设置要使用的TLS版本,参见this answer
  • 我正在 Java 1.6 中尝试这种方式:stackoverflow.com/questions/33517476/…
  • 默认的连接方式是SSL、TLS1.0还是TLS1.2?

标签: java ssl httpsurlconnection


【解决方案1】:

您必须创建一个SSLContext 来设置协议:

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

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

这应该可以解决问题。

【讨论】:

  • 什么是 trustCerts 以及如何创建/获得一个?
  • 如果有人想知道 init() 参数,这里是文档所说的:“前两个参数中的任何一个都可能为空,在这种情况下,将搜索已安装的安全提供程序以获得最高优先级相应工厂的实现。同样,安全随机参数可能为空,在这种情况下将使用默认实现。"
  • 请参阅stackoverflow.com/questions/1201048/…,了解 trustCerts 的简单、不安全、全信任的实现
【解决方案2】:

您还可以使用 JDK 1.7 设置 TLS 1.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());

【讨论】:

    【解决方案3】:
    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

    【讨论】:

    • 是的,它可能可以......但它有什么作用?
    • 这有助于在 java 7 中设置 tls 1.2,在 java 7 中默认情况下不启用此功能
    • 默认使用什么 SSL、TLS1.0 或 TLS1.2 ?
    【解决方案4】:
        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?

    【讨论】:

    • (0) 这不是一个答案,StackExchange 的设计目的是在标记为问题的部分中有问题,在标记为答案的部分中有答案。 (1) 这会为您直接使用的SSLSocket 设置协议和密码套件,而不是为创建自己的套接字的HttpsURLConnection 设置协议和密码套件。 4岁答对地址HttpsURLConnection。 (2) 尽管您正式启用了 1(.0),1.1,1.2,但您指定了仅在 1.2 中有效的密码套件,因此如果对等方同意 1.2 并且该密码套件您将获得 1.2,否则你会失败;你永远不会得到 1.1 或 1.0。
    猜你喜欢
    • 2016-02-04
    • 2015-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    相关资源
    最近更新 更多