如何强制Java服务器仅接受TLS 1.2并拒绝TLS 1.0和TLS 1.1连接

29

我有一个运行在Java 7上的HTTPS Web服务。我需要进行更改,使此服务仅接受TLS1.2连接并拒绝SSL3、TLS1.0和TLS1.1。

我已添加以下Java参数,以使TLS1.2成为最高优先级。

-Dhttps.protocols=TLSv1.2

但它也接受来自Java客户端的TLS1.0连接。如果客户端也使用上述Java参数运行,则连接为TLS1.2,但如果客户端未使用此参数运行,则连接为TLS1.0。

我在jdk/jre/lib/security文件夹中尝试了一些java.security文件的操作。

目前我已禁用以下算法:

jdk.certpath.disabledAlgorithms= MD2, MD4, MD5, SHA224, DSA, EC keySize < 256, RSA keySize < 2048, SHA1 keysize < 224
jdk.tls.disabledAlgorithms=DSA, DHE, EC keySize < 256, RSA keySize < 2048, SHA1 keysize < 224

我正在使用Java 7更新版79。 我不倾向于拦截每个连接并检查TLS版本。

我的服务器证书是使用MD5和RSA算法生成的2048位证书。

如果禁用算法列表中有RSA而不是RSA keySize < 2048,则会收到SSLHandShakeError错误消息:

没有通用密码套件。

我的测试程序正在运行来自以下URL的HTTP服务器: http://www.herongyang.com/JDK/HTTPS-HttpsEchoer-Better-HTTPS-Server.html

请告诉我如何使Java只接受TLS1.2连接。


SSLContext.getInstance("TLSv1.2") 能用吗? - user5266804
@user5266804 不,它不会。SSLContext.getInstance 方法基本上需要将 SSLTLS 作为参数传入。我敢打赌,在底层,Sun 提供程序甚至不关心您传递了什么字符串:您始终会得到由 JSSE 提供的“TLS 引擎”。 - Christopher Schultz
sysprop htts.protocols 没有起作用,因为它(以及 https.cipherSuites)只影响使用 HttpsURLConnection出站 连接,而不影响入站连接或直接使用 SSL[Server]SocketSSLEngine。@ChristopherSchultz:JCA查找仅接受由提供程序预定义的字符串(忽略大小写),对于j7 JSSE来说,这些字符串是 Default SSL SSLv3 TLS TLSv1 TLSv1.1 TLSv1.2 -- 后两个在初始启用的协议方面有所不同,但所有协议都使用相同的代码,并且可以启用任何实现协议的子集,除了 disabledAlgorithms secprop 中的那些。 - dave_thompson_085
5个回答

49
我找到了解决方法。我设置了
jdk.tls.disabledAlgorithms= SSLv2Hello, SSLv3, TLSv1, TLSv1.1

在服务器上的文件jre/lib/security/java.security中设置此项后,服务器只接受TLS1.2连接并拒绝较低的安全协议版本。


这个应该在哪里设置? - vikifor
1
你需要将此设置在“java.security”文件中,该文件可以在<JDK>/jre/lib/security文件夹中找到。 - PankajSays
这些更改不需要重新编译,因为它们不是代码更改。 - PankajSays
1
我正在使用以下属性 jdk.tls.disabledAlgorithms=EC,ECDHE,DHE,TLSv1.2,SSLv3,RSA keySize < 2048但是当我获取getSupportedCipherSuites()时,它也显示已禁用的密码套件。 - userLearner
@userLearner 不需要重新加载任何设置。 - pascalre
显示剩余3条评论

3

我已经在“/java/jdk1.7.0_79/jre/lib/security-java.security”文件中做出了相同的更改,但是一些客户仍然能够使用SSL协议调用我的服务。

更改内容:

jdk.tls.disabledAlgorithms=SSL,SSLv2,SSLv3, TLSv1, TLSv1.1,MD5, SSLv3, DSA, RSA keySize < 2048

2
但是仍然有一些客户端可以使用SSL协议调用我的服务。 - blissini
尝试回答这个非常古老的问题的方法是将SSLv2Hello添加到disabledAlgorithms中。 - SensorSmith

2

只是一个小备注;

在问题中,您声明使用MD5生成了2048大小的证书。但在证书路径算法中禁用了MD5,因此这通常不起作用。其次,使用MD5哈希生成的服务器证书被现代浏览器(如Internet Explorer 10 / Edge)禁止。

我建议您至少使用SHA256或<哈希生成您的服务器证书。


1

截至2021年11月更新

从JDK版本11.0.11开始,默认情况下禁用TLS 1.0和TLS 1.1,您无需进行任何操作。

此修复程序还被反向移植到了JDK 7u301和8u291。

详情请参见:JDK-8202343:禁用TLS 1.0和1.1

您仍然可以通过更改java.security来显式启用TLS 1.0 / 1.1,如接受的答案中所述。


尽管在j9中,java.security位于conf/security而不是jre/lib/security - dave_thompson_085

1

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