SSLContext.getInstance("TLS")漏洞

3
我们收到了报告称 SSLContext.getInstance("TLS") 存在漏洞。推荐的修复方法是使用 SSLContext.getInstance("TLSv1.2")
我了解到自2021年4月起,Java实现已禁用TLSv1.1和TLSv1,但当我尝试使用此修复方法时,我发现这将禁用TLSv1.3(即使我通过sslSocket.setEnabledProtocols(protocols)添加它)。
当我使用SSLContext.getInstance("TLSv1.3")时,sslSocket.getEnabledProtocols()返回TLSv1.3和TLSv1.2,如果服务器端仅支持TLSv1.2,则建立连接。
对我来说,这是出乎意料的。对我来说,这将是一种“算法降级”。
文档只表示“可能支持其他SSL/TLS版本”,因此当我指定“TLSv1.3”时,我不能期望回退到“TLSv1.2”能够工作,对吗?
尽管看起来SSLContext.getInstance参数是支持的最高TLS版本。
那么,实现服务器端可能支持TLSv1.2或TSLv1.3或两者的SSL连接的正确方法是什么(并且不会报告漏洞)?
问候, Andreas

getInstance(1.2)会为1.2(如果您未禁用它们,则为更低版本)设置协议和密码套件;如果我同时将setEnabledProtocols设置为添加1.3并将setEnabledCipherSuites设置为添加所有或一些1.3套件,那么它可以工作。但是,硬编码当前的1.3套件并不健壮,因为可能会开发新的套件,也不希望启用所有支持的套件,因为某些旧的套件很差,所以这种方法有点丑陋。在JSSE中,getInstance(1.3)确实支持1.2(如果未禁用),尽管没有记录,因此不能“保证”。 - dave_thompson_085
1个回答

4
您并未说明使用的漏洞检查工具是什么,但该报告与此相符: 如果是这样,请阅读以下Sonar错误报告: 它指出SSLContext.getInstance(...)中的参数不限制使用的TLS版本。 因此,漏洞报告是一个错误的阳性结果。 您可以通过使用不同的值来消除误报。 但请注意,这并未解决潜在/实际漏洞。
要正确限制用于特定连接的SSL/TLS版本,可以配置SSLEngine对象。
serverEngine = serverSslContext.createSSLEngine();
serverEngine.setEnabledProtocols(new String[] { "TLSv1.2", "TLSv1.3" });

或者,你可以通过在命令行上设置JVM属性来限制整个JVM:

java -Dhttps.protocols="TLSv1.2,TLSv1.3" \
     -Djdk.tls.client.protocols="TLSv1.2,TLSv1.3" <MyApp>

参考资料:


我们使用Veracode,但我也发现了你上面提到的Sonar评论。我们已经通过setEnabledProtocols限制了版本。 - Andreas Mueller
https.protocols 只控制 HttpsURLConnection(尽管 Oracle 页面并不像它应该的那样清晰)。jdk.tls.client.protocols 是一个默认值(目前不会改变任何内容),但不是约束条件。OP 使用的是 socket 而不是 engine,'v2' 和 'v3' 是错误的。 - dave_thompson_085

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