JDK 8u161中Apache FTPS客户端中的SSL会话重用
使用Apache Commons-Net的FTPSClient
连接到现代FTP / S服务器不起作用。 原因是它们需要重用SSL会话,即需要重新使用来自控制连接的SSL会话进行数据连接。
这通常可以在服务器中停用,但也就是说
- 不安全
- 并不总是一个选项(因为服务器可能不在您的控制之下)
正确的解决方案是让客户端实际重用会话。 Commons-Net存在一个漏洞 ,但看起来不会很快得到解决。
此外,还有一个由Cyberduck(一个FTP客户端应用程序)的作者创建的“reflection黑客”,它在他们的bugtracker中进行了描述,并且在博客文章中更深入地描述。 StackOverflow上还有一篇相关文章描述了这个解决方案。 他们使用reflection来访问JDK的SSLSessionContext
的内部缓存并注入一个新条目。
这个hack工作正常,直到JDK 8u161和9.0.4(?),其中引入了对更改日志中描述的SSL的一些更改。 显然,一些实现细节已经改变,导致黑客不再工作。
据我所知,现在有以下选项:
- 继续使用JDK 8u152,直到有人找到解决方案/ apache-commons-net得到修补/ JDK更改被回滚(不是真正的选项,因为这会切断生产系统的安全更新)
- 使用不同的FTPS客户端(我能找到的唯一替代方案是专有且非常昂贵)
- 尝试对
SSLSessionContext
实现的更改进行反向工程以查找新的解决方法。 这看起来不仅仅是一项非常重要的任务 – 解决方案可能会再次成为黑客,因此可能随时再次破裂。 - 不要再使用FTP / S.
谁能建议如何在这里继续?
相关链接:
- http://mail.openjdk.java.net/pipermail/security-dev/2016-December/015254.html
- https://bugs.openjdk.java.net/browse/JDK-8170813
- https://issues.apache.org/jira/browse/NET-426
这里描述了可能的解决方案。
从本质上讲,它正在将改变的行为从JDK8u161恢复到以前的工作方式。 您需要设置系统属性
jdk.tls.useExtendedMasterSecret
这样做是false
。
有两种方法:
- 调用
System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
在启动FTP / S连接之前 - 使用
java -Djdk.tls.useExtendedMasterSecret=false [...]
将属性传递给java进程java -Djdk.tls.useExtendedMasterSecret=false [...]
请记住,此解决方案会禁用JVM范围内的安全增强function – 请谨慎操作。