java - 将 Java Apache FTPClient 用于 FTP TLS 时获取 "Remote host closed connection during handshake"

标签 java apache ftp ftps apache-commons-net

<分区>

我在 Windows 10 64x 上为 FTP TLS (org.apache.commons.net.ftp) 运行了一个 Java (1.8) 程序:

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 解决方案?

My ftp Object

最佳答案

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

450 TLS session of data connection has not resumed or the session does not match the control connection

一些 FTP 服务器确实要求您为数据连接重用 TLS session 。

Apache Commons Net 库(尚未)原生支持此功能,但实现起来并不困难。

如何做到这一点,在我的回答中显示:
How to connect to FTPS server with data connection using same TLS session?

关于java - 将 Java Apache FTPClient 用于 FTP TLS 时获取 "Remote host closed connection during handshake",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46631315/

相关文章:

java - 返回 ArrayList 时,我是否必须同时返回 <Type> ?

javax.xml,XPath 不是从具有命名空间的 XML 中提取的

apache - 在哪里可以找到 WAMP 错误日志?

c# - 如何在不下载的情况下使用 FTP 服务器上的数据库?

objective-c - 从 iOS 应用程序上传文件到 ftp

java - 返回字符串长度为 0 的 HttpResponse

java - 如果我通过 Selenium Webdriver 和 Java 知道相应的文本,如何提取 DOM 元素的 ID 属性

java - 如何在 PHP 中执行 java 函数/脚本

php - rename() PHP 函数找不到目录,即使它在那里?

android - 从服务器上传文件时出现错误文件号套接字异常