首页 >Java >java教程 >如何通过 Apache Commons Net 重用 FTPS 中数据连接的 TLS 会话?

如何通过 Apache Commons Net 重用 FTPS 中数据连接的 TLS 会话?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-11 22:42:03379浏览

How to Reuse the TLS Session for Data Connections in FTPS with Apache Commons Net?

如何使用相同的 TLS 会话通过数据连接连接到 FTPS 服务器

Apache Commons Net FTPS 实现不会自动重用 TLS连接到某些 FTPS 服务器时用于数据连接的会话。这可能会在尝试数据连接时导致 TLS 握手错误。

要确保数据连接使用与控制连接相同的 TLS 会话:

  1. 检查 FTPS 是否服务器支持 TLS 会话重用: 某些服务器(例如 FileZilla Server)强制数据连接重用 TLS 会话。
  2. 使用自定义代码重用会话: 您可以覆盖 _prepareDataSocket_ FTPSClient 类中的方法来手动设置数据连接的会话。
@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("sessionsByHostAndPort");
                    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 sessionsByHostAndPort 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));
            }
        }
    }
}
  1. 重写 Spring Integration 的 createClientInstance(): 创建一个返回具有 _prepareDataSocket_ 覆盖的 FTPSClient。
  2. 将 jdk.tls.useExtendedMasterSecret 设置为 false(Java 8u161 及更高版本): 这是 JDK 8u161 中 SSLHandshakeException 的解决方法。
System.setProperty("jdk.tls.useExtendedMasterSecret", "false");

以上是如何通过 Apache Commons Net 重用 FTPS 中数据连接的 TLS 会话?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn