Java FTP4j无法使用FTPES(数据连接的TLS会话未恢复或会话与控制连接不匹配)

Java FTP4j无法使用FTPES(数据连接的TLS会话未恢复或会话与控制连接不匹配),java,ftp,filezilla,ftps,ftp4j,Java,Ftp,Filezilla,Ftps,Ftp4j,我正在尝试使用ftp4j lib从FileZilla FTP servicer和TLS获取文件列表 import it.sauronsoftware.ftp4j.FTPClient; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import java.io.FileInputStream; import java.security.KeyStore; import java.security.S

我正在尝试使用ftp4j lib从FileZilla FTP servicer和TLS获取文件列表

import it.sauronsoftware.ftp4j.FTPClient;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Arrays;

public class FTP {

    public static void main(String args[]) throws Exception {
        System.setProperty("http.protocols", "TLSv1,TLSv1.1,TLSv1.2"); 
        //tried to avoid closing connection during the handshake

        //load and set certificate
        KeyStore keyStore = KeyStore.getInstance("JKS");
        keyStore.load(new FileInputStream("mykeystore.jks"), "root12".toCharArray());

        FTPClient client = new FTPClient();

        SSLContext sslContext = null;
        try {
            javax.net.ssl.TrustManagerFactory tmf = javax.net.ssl.TrustManagerFactory
                    .getInstance(javax.net.ssl.KeyManagerFactory
                            .getDefaultAlgorithm());
            tmf.init(keyStore);
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
        } catch (Exception e) {
            e.printStackTrace();
        }

        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        client.setSSLSocketFactory(sslSocketFactory);
        client.setSecurity(FTPClient.SECURITY_FTPES);

        client.setCharset("UTF-8");
        client.setPassive(true);
        String[] arg = client.connect("localhost", 21);
        System.out.println(Arrays.toString(arg));

        client.login("admin", "pass"); //OK
        client.noop(); // aka Ping is OK
        String s = client.currentDirectory(); //OK
        client.changeDirectory("/"); //OK
        String[] files = client.listNames(); //Exception here
        System.out.println(Arrays.toString(files));
        client.disconnect(true);
    }
}
我有个例外

线程“main”it.sauronsoftware.ftp4j.FTPException中出现异常 [代码=450,消息=数据连接的TLS会话未恢复,或 会话与上的控制连接]不匹配 it.sauronsoftware.ftp4j.FTPClient.listNames(FTPClient.java:2407)位于 main(FTP.java:49)

我尝试使用活动模式,但也没有帮助(ping命令后失败)

线程“main”it.sauronsoftware.ftp4j.FTPException中出现异常 [代码=421,消息=拒绝命令,请求的IP地址不存在] 匹配控制连接IP。]

您能回答我做错了什么吗?或者ftp4j库是否支持FTPES和TLS

FileZilla服务器TLS配置的屏幕截图:


ftp4j库不支持FTPS/TLS。如果不是这样,你一开始就不会出错

FileZilla FTP服务器是FTP服务器之一,它要求客户端从FTP控制连接重新使用TLS/SSL会话进行数据连接:

这增加了安全性,使攻击者更难进行攻击

我不知道ftp4j是否支持这个重用

可供选择的解决办法是:

  • 使用Apache Commons网络库中的Java FTP客户端。虽然它本身不支持重用,但添加支持很容易。看
  • 由于您拥有FTP服务器,因此可以禁用重用要求。请参阅使用PROT P选项(屏幕截图上)时在数据连接上要求TLS会话恢复。尽管如上所述,它对安全性有一定的影响


请尝试删除此复选框,因为它对我有帮助。

第二种解决方案不合适,在我的情况下,我无法更改ftp服务器的设置。第一个太复杂了(迁移到ApacheLib),所以它应该是合理的(例如,一些证明ftp4j不支持TLS),我没有说“ftp4j不支持TLS”。当然,它确实支持它。您知道为什么我的代码不能与filezilla一起工作吗?因为它不会将控制连接的TLS会话重新用于数据连接。我相信我的回答说得很清楚。与fpt4j的开发人员确认,不可能与该库重复使用会话。这是一种解决方法,但不是解决方案(我无法更改远程服务器设置)。此外,我在回答中已经提出了这一点,因此您的回答不会带来任何新内容。