如何在 Java 7 中启用 TLS 1.2

Posted

技术标签:

【中文标题】如何在 Java 7 中启用 TLS 1.2【英文标题】:How to enable TLS 1.2 in Java 7 【发布时间】:2017-01-02 14:27:40 【问题描述】:

我正在尝试在使用 JBoss 6.4 和 Java 1.7 的 Web 应用程序中启用 TLS 1.2。我的应用程序环境中有-Dhttp.protocols = TLSv1.2,但它似乎对我不起作用。

我可以做些什么来启用 TLS 1.2?

我写了一个简单的程序

context = SSLContext.getInstance("TLSv1.2");
context.init(null,null,null);
SSLContext.setDefault(context); 
SSLSocketFactory factory = (SSLSocketFactory)context.getSocketFactory();
SSLSocket socket = (SSLSocket)factory.createSocket();
protocols = socket.getEnabledProtocols();

在应用程序中运行此程序后,TLS 1.2 将启用。我不想运行这个程序,但我想在应用程序启动期间直接启用它。有什么办法吗?

【问题讨论】:

sysprop https.protocols 仅在与两个 s 拼写时才有效,并且仅适用于使用 URL.openConnection 而非其他方式(如 SSLSocketFactory)建立的连接 【参考方案1】:

将此参数添加到JAVA_OPTS 或Maven 中的命令行: -Dhttps.protocols=TLSv1.2

【讨论】:

【参考方案2】:

有很多建议,但我发现其中两个最常见。

回复。 JAVA_OPTS

我在启动程序之前首先在命令行上尝试了export JAVA_OPTS="-Dhttps.protocols=SSLv3,TLSv1,TLSv1.1,TLSv1.2",但它对我不起作用。

回复。构造函数

然后我在启动类构造函数中添加了以下代码,它对我有用。

try 
        SSLContext ctx = SSLContext.getInstance("TLSv1.2");
        ctx.init(null, null, null);
        SSLContext.setDefault(ctx);
 catch (Exception e) 
        System.out.println(e.getMessage());

坦率地说,我不知道为什么 ctx.init(null, null, null); 但所有 (SSL/TLS) 对我来说都很好。

回复。 System.setProperty

​​>

还有一个选项:System.setProperty("https.protocols", "SSLv3,TLSv1,TLSv1.1,TLSv1.2");。它也将进入代码,但我没有尝试过。

【讨论】:

这应该是公认的答案。由于 java 在 Java 7_80 中选择,-Dhttps.protocols="TLSv1.2" 属性似乎存在错误。 我也尝试过使用 Java 选项(例如 https.protocols)但没有奏效 - 似乎它甚至没有查看该选项。【参考方案3】:

即使客户端和服务器都设置为 TLSv1.2 证书正确且 java 为 1.8.0_141,我在连接到 RDS Oracle 时也遇到了类似的问题 所以最后我不得不在Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files应用补丁

应用补丁后问题消失,连接正常。

【讨论】:

【参考方案4】:

我通过使用解决了这个问题

Service.setSslSecurityProtocol(SSLSecurityProtocol.TLSv1_2);

【讨论】:

我找不到该行的包【参考方案5】:

要在 JRE7u_80 中强制启用 TLSv1.2,我必须在创建 JDBC 连接之前使用以下代码 sn-p。

import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import javax.net.ssl.SSLContextSpi;
import sun.security.jca.GetInstance;
import sun.security.jca.ProviderList;
import sun.security.jca.Providers;

public static void enableTLSv12ForMssqlJdbc() throws NoSuchAlgorithmException

    ProviderList providerList = Providers.getProviderList();
    GetInstance.Instance instance = GetInstance.getInstance("SSLContext", SSLContextSpi.class, "TLS");
    for (Provider provider : providerList.providers())
    
        if (provider == instance.provider)
        
            provider.put("Alg.Alias.SSLContext.TLS", "TLSv1.2");
        
    

能够连接到装有 SQL Server 2017 和启用 TLSv1.2 的操作系统的 Windows 10。

【讨论】:

【参考方案6】:

您可能应该查看通过-Djdk.tls.client.protocols=TLSv1.2 控制底层平台 TLS 实现的配置。

【讨论】:

似乎它只适用于 JDK 1.7.0_95 或更高版本,但这里的问题是 JDK 1.7 上的最后一次公开发布/更新是 JDK 1.7.0_80,所以从技术上讲,这适用于曾经使用过某个版本的人JDK 拥有 Oracle 支持或 Oracle 客户!请让我知道它是否适用于 JDK 1.7.0_80【参考方案7】:

陈述的答案是正确的,但我只是分享一个适用于我的案例的额外问题:除了使用setProtocol/withProtocol,您可能还有一些讨厌的罐子甚至不会消失如果有合适的罐子和旧罐子:

删除

<dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.1</version>
</dependency>

保留

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.2</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.6</version>
</dependency>

Java 向后兼容,但大多数库不向后兼容。每一天过去,我都希望共享库因缺乏问责制而被取缔。

更多信息

java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

【讨论】:

Sridhar,因此随着这些更改以及 Dhttp.protocols = TLSv1.2 1.7.0_80 默认支持 TLSv1.2(因为我看到 sslHandshake 正在使用 TLSv1)或者我需要升级我们的JDK到更高版本?即使我在 Eclipse 运行时环境中提供“-Dhttps.protocols = TLSv1.2”。或 catalina 属性中的“https.protocols = TLSv1.2” - 它不起作用! 我感受到你的痛苦。我了解并非在所有情况下都可以升级。它在 java 7 上对我有用,但我需要我的架构师找出这个不需要的 jar。 是的,谢谢你的建议,但不知何故它对我不起作用,每次默认为 TLSv1 时都会发生同样的情况。【参考方案8】:

System.setProperty("https.protocols", "TLSv1.2"); 在我的情况下工作。你在应用程序中检查过吗?

【讨论】:

这是一款 COTS 产品。我不能用那个。至少我不知道在系统启动时如何使用它 在这种情况下你检查过developer.jboss.org/thread/251967?start=0&tstart=0吗?【参考方案9】:

为 java 应用程序添加以下选项:

-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2  

【讨论】:

我有一个问题,这个改变有什么作用?它是否为所有传入和出站连接请求启用 TLS?有没有办法记录 TLS 握手?【参考方案10】:

您可以将 Java 7 版本升级到 1.7.0_131-b31

对于 Oracle 站点中的 JRE 1.7.0_131-b31:

TLSv1.2 和 TLSv1.1 现在默认在 TLS 客户端上启用 端点。这与 JDK 8 中已经发生的行为类似 发布。

【讨论】:

你能分享一个链接吗? oracle.com/technetwork/java/javase/7u131-relnotes-3338543.html 这是一个带有发行说明的页面。 jdk怎么下载? @UdayReddy 您需要成为商业用户才能下载。 它适用于我的非商业版本 jdk1.7.0_80 - 但我必须按照 Ankit 和 Meeraj 的建议添加 -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2

以上是关于如何在 Java 7 中启用 TLS 1.2的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Nginx 中启用 TLS 1.2?

如何在 Spring-boot 上启用 TLS 1.2?

在高级设置中启用 TLS 1.0、TLS 1.1 和 TLS 1.2,

如何在 Android 应用程序中启用 TLS 1.2 支持(在 Android 4.1 JB 上运行)

如何在Android应用程序中启用TLS 1.2支持(在Android 4.1 JB上运行)

如何在 WebSphere 7.0.0.45 中使用强密码套件配置 TLS 1.2 协议?