解决 FTPS 数据连接的 TLS 会话重用问题
建立 FTPS 连接时,数据连接重用 TLS 至关重要为控制连接建立的会话。这可确保服务器验证两个连接的客户端身份。然而,包括 FileZilla 在内的一些 FTP(S) 服务器强制执行此要求。
许多 Java FTPS 客户端使用的 Apache Commons Net 库缺乏此会话重用功能。为了克服这个限制,建议检查 Cyberduck FTP(S) 客户端的实现,它支持 TLS/SSL 会话重用。
特别要关注 prepareDataSocket 方法FTPClient.java。此方法允许重用来自数据连接的控制连接的 TLS/SSL 会话。
这是一个示例 prepareDataSocket 方法:
@Override protected void _prepareDataSocket_(final Socket socket) { if (preferences.getBoolean("ftp.tls.session.requirereuse")) { if (socket instanceof SSLSocket) { // Control socket is SSL final SSLSession session = ((SSLSocket) _socket_).getSession(); if (session.isValid()) { final SSLSessionContext context = session.getSessionContext(); context.setSessionCacheSize(preferences.getInteger("ftp.ssl.session.cache.size")); try { final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache"); sessionHostPortCache.setAccessible(true); final Object cache = sessionHostPortCache.get(context); final Method putMethod = cache.getClass().getDeclaredMethod("put", Object.class, Object.class); putMethod.setAccessible(true); Method getHostMethod; try { getHostMethod = socket.getClass().getMethod("getPeerHost"); } catch (NoSuchMethodException e) { // Running in IKVM getHostMethod = socket.getClass().getDeclaredMethod("getHost"); } getHostMethod.setAccessible(true); Object peerHost = getHostMethod.invoke(socket); putMethod.invoke(cache, String.format("%s:%s", peerHost, socket.getPort()).toLowerCase(Locale.ROOT), session); } catch (NoSuchFieldException e) { // Not running in expected JRE log.warn("No field sessionHostPortCache in SSLSessionContext", e); } catch (Exception e) { // Not running in expected JRE log.warn(e.getMessage()); } } else { log.warn(String.format("SSL session %s for socket %s is not rejoinable", session, socket)); } } } }
此方法确保来自控制连接的 TLS/SSL 会话重用于数据连接。
其他注意事项:
在 Java 8u161 及更高版本中,您可能会遇到与扩展的主密钥扩展支持。要缓解此问题,请通过将 jdk.tls.useExtendedMasterSecret 系统属性设置为 false 来禁用此扩展。
如果您仍然遇到问题,请参阅 Jira 票证 NET-408 以获取替代实现和其他相关信息。
通过实施这些步骤并利用 Cyberduck FTP(S) 客户端实现,您可以建立具有 TLS 会话重用的 FTPS 连接,满足客户端 FTPS 服务器的要求。
以上是如何解决 Java FTPS 客户端中的 TLS 会话重用问题?的详细内容。更多信息请关注PHP中文网其他相关文章!