当前位置: 首页 > 知识库问答 >
问题:

当使用JavaApache FTPClient for FTP TLS获取"远程主机在握手过程中关闭连接"[重复]

戚建德
2023-03-14

我在Windows1064X上运行了一个Java(1.8)程序,用于FTP TLS(org.apache.commons.net.FTP):

FTPSClient ftpClient = new FTPSClient();

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
// LISTENER
ftpClient.addProtocolCommandListener(
    new PrintCommandListener(new PrintWriter(System.out), true));

ftpClient.connect(server);
ftpClient.login(user, pass);

// Enter local passive mode
ftpClient.enterLocalPassiveMode();
// useEpsvWithIPv4
ftpClient.setUseEPSVwithIPv4(true);
// Set protection buffer size
ftpClient.execPBSZ(0);
// Set data channel protection to private
ftpClient.execPROT("P");

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");

ftpClient.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());

ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

System.out.println("Remote system is " + 
ftpClient.getEnabledCipherSuites());

System.out.println("SSL: " + 
ftpClient.getEnableSessionCreation());
// PROTOCOLOS
String[] Protocols = ftpClient.getEnabledProtocols();
System.out.println("Protocols " + Protocols);
// AUTH
boolean Auth = ftpClient.getNeedClientAuth();
System.out.println("Auth: " + Auth);
ftpClient.getWantClientAuth();
ftpClient.getTrustManager();
ftpClient.feat();              

// APPROACH #1: using retrieveFile(String, OutputStream)
String remoteFile1 = "/readme.txt";
File downloadFile1 = new File("C:\\readme.txt");
OutputStream outputStream1 = new BufferedOutputStream(new 
FileOutputStream(downloadFile1));
ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();

对于第一个FTP服务器(Microsoft FTP服务),工作正常!调试:

run:
220 Microsoft FTP Service
AUTH TLS
234 AUTH command ok. Expecting TLS Negotiation.
USER *******
331 Password required for demo.
PASS *******
230 User logged in.
PBSZ 0
200 PBSZ command successful.
PROT P
200 PROT command successful.
TYPE I
200 Type set to I.
SSL: true
SYST
215 Windows_NT
Remote system is Windows_NT
Protocols [Ljava.lang.String;@3f2a3a5
Auth: false
FEAT
211-Extended features supported:
 LANG EN*
 UTF8
 AUTH TLS;TLS-C;SSL;TLS-P;
 PBSZ
 PROT C;P;
 CCC
 HOST
 SIZE
 MDTM
 REST STREAM
211 END
EPSV
229 Entering Extended Passive Mode (|||1025|)
RETR /readme.txt
125 Data connection already open; Transfer starting.
226 Transfer complete.
QUIT
221 Goodbye.
BUILD SUCCESSFUL (total time: 7 seconds)

对于第二个FTP服务器(FileZilla Server 0.9.59 beta)出错,调试:

run:
220-FileZilla Server 0.9.59 beta
220-written by Tim Kosse (tim.kosse@filezilla-project.org)
220 Please visit https://filezilla-project.org/
AUTH TLS
234 Using authentication type TLS
USER *******
331 Password required for xxx
PASS *******
230 Logged on
PBSZ 0
200 PBSZ=0
PROT P
200 Protection level set to P
TYPE I
200 Type set to I
SSL: true
SYST
215 UNIX emulated by FileZilla
Remote system is UNIX emulated by FileZilla
Protocols [Ljava.lang.String;@246ae04d
Auth: false
FEAT
211-Features:
 MDTM
 REST STREAM
 SIZE
 MLST type*;size*;modify*;
 MLSD
 AUTH SSL
 AUTH TLS
 PROT
 PBSZ
 UTF8
 CLNT
 MFMT
 EPSV
 EPRT
211 End
EPSV
229 Entering Extended Passive Mode (|||14393|)
RETR /readme.txt
150 Opening data channel for file download from server of "/readme.txt"
Error: Remote host closed connection during handshake
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
QUIT
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1002)
450 TLS session of data connection has not resumed or the session does not match the control connection
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
    at org.apache.commons.net.ftp.FTPSClient._openDataConnection_(FTPSClient.java:646)
    at org.apache.commons.net.ftp.FTPClient._retrieveFile(FTPClient.java:1899)
    at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1885)
    at ftps.App_FTP.main(App_FTP.java:96)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:505)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:983)
    ... 7 more
BUILD SUCCESSFUL (total time: 5 seconds)

使用FileZilla客户端工作正常(下载/上传文件),但使用Java代码我不能做什么只是连接和登录。有什么建议吗?或任何其他自动FTP TLS的解决方案?

我的ftp对象

共有2个答案

吉和同
2023-03-14

我使用Cyberduck库解决了这个问题。https://github.com/iterate-ch/cyberduck
首先,为什么会出现这种握手问题,因为某些先进的FTP服务器只允许一个会话进行连接和数据传输。

1)控制会话-

那么如何解决这个问题呢。

步骤1-:

首先,您需要从GitHub签出cyberduck回购协议。从这里开始-:https://github.com/iterate-ch/cyberduck

步骤2-:您将在checkout repo FTP和核心模块中看到FTP和核心模块

步骤3-:将此模块转换为maven并为其创建jar。

步骤4-:将这个jar添加到您的项目中,但是这个jar还需要其他依赖项,因此也相应地将这些依赖项添加到项目构建路径中。

步骤5-:代码片段。

public class TestFTPS {
    public static void main(String[] args) throws SocketException, IOException {
        TrustManager[] trustManagers = new TrustManager[] { new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                // TODO Auto-generated method stub
                return null;
            }
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // TODO Auto-generated method stub
            }

            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // TODO Auto-generated method stub
            }
        } };
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustManagers, new SecureRandom());
        } catch (Exception e) {
            e.printStackTrace();
        }
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        Protocol protocol = new FTPTLSProtocol();
        FTPClient client = new FTPClient(protocol, sslSocketFactory, sslContext);
        client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
        client.connect(ftphostname, port);
        client.execAUTH("TLS"); //SSL
        System.out.println(client.getReplyCode());
        if (client.login(username, password)) {
            client.execPBSZ(0);
            client.execPROT("P");
            String date = "Testing Data Send to provide FTP location";
            client.setFileType(FTP.BINARY_FILE_TYPE);
            client.enterLocalPassiveMode();
            InputStream is = new ByteArrayInputStream(date.getBytes());
            client.storeFile("test.txt", is);
            System.out.print(client.getReplyCode());
        }
    }
}

步骤6-:运行此代码后,您的文件将成功传输到ftp位置。

注意-:请在您的项目中添加所需的jar

希望这对你有帮助。

周育
2023-03-14

重要信息不是异常消息本身,而是日志中的此消息:

450数据连接的TLS会话未恢复或会话与控制连接不匹配

某些FTP服务器确实要求您重新使用TLS会话进行数据连接。

ApacheCommonsNetLibrary本机还不支持这一点,但实现它并不困难。

如何做到这一点,如我对以下问题的回答所示:
如何使用相同的TLS会话通过数据连接连接到FTPS服务器?

 类似资料:
  • 感谢您抽出时间阅读我的问题-我正在使用EclipseIDE。我希望Jsoup连接https url-https://www.icegate.gov.in/使用 但它在线程“main”javax中给出了错误,而当我对其他https(如linkedin)使用相同的代码时,它就工作了。。。我不知道如何解决这个问题。 我获得了该网站的证书,并安装在我的jre/lib/security文件夹中,但它对我也没

  • 我试图连接到需要显式FTP在TLS的FTP。我正试图从我的本地机器上做这件事。 下面是我使用的代码 当我跑的时候,我得到下面的异常 下面是我从Java CommandListener获得的日志 下面是我尝试使用FileZilla连接时的日志。它连接良好,我可以传输文件。但是当我尝试使用Java时,它没有连接 你们能帮忙吗? 亲切的问候乔恩

  • 我正在尝试连接到SOAPendpoint。 使用上面的方法,我不断得到下面的错误 java.lang.Thread.run(未知来源)[na: 1.8。0_191]原因:com.sun.xml.messaging.saaj.SOAPExceptionImpl:消息发送失败com.sun.xml.messaging.saaj.client.p2p。HttpSOAPConnection.post(Ht

  • 我们为特定的IP地址配置了一个大型F5负载平衡器虚拟服务器,它将传入的https请求重定向到多个Windows服务器,在这些服务器上可以生成响应。 我正在使用SoapUI测试通过大F5中虚拟服务器的IP地址对这些windows服务器的访问。 使用由组织生成的服务器和客户机证书,我们在该组织中也进行了此设置,并通过SoapUI发送请求,我得到了预期的响应。 业务要求要求由Thawte签署商业证书。

  • SSLHandShakeException:尝试发布到以下URL时,在握手过程中发生远程主机关闭连接异常: https://testapi.title365.com/keystoneB2b/ordersservice.aspx 谁能帮帮忙吗?

  • 论坛上充斥着这个问题,但我找不到解决办法。我尝试连接WS,但没有成功。我试图更新cacerts文件,但没有效果。 日志是: 谢谢你的帮助