When using Java Apache FTPClient for FTP TLS getting quot;Remote host closed connection during handshakequot;(当使用 Java Apache FTPClient 进行 FTP TLS 获取“握手期间远程主机关闭连接时)
问题描述
我在 Windows 10 64x 上为 FTP TLS (org.apache.commons.net.ftp) 运行了一个 Java (1.8) 程序:
I ran a Java (1.8) program on Windows 10 64x for 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 服务)工作正常!调试:
For the first FTP server (Microsoft FTP Service) works just fine! debug:
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)出错,调试:
For the second FTP server (FileZilla Server 0.9.59 beta) goes wrong, debug:
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 的解决方案?
Using the FileZilla client works fine (download/upload files) but using the Java code I can't do nothing just connect and logon. Any suggestion? or any other solution for a automated FTP TLS?
我的 ftp 对象
推荐答案
重要的信息不是异常信息本身,而是日志中的这条信息:
The important information is not the exception message itself, but this message in the log:
450 数据连接的 TLS 会话未恢复或会话与控制连接不匹配
450 TLS session of data connection has not resumed or the session does not match the control connection
某些 FTP 服务器确实要求您重复使用 TLS 会话进行数据连接.
Some FTP servers do require that you reuse the TLS session for data connections.
Apache Commons Net 库(尚未)原生支持此功能,但实现起来并不难.
This is not (yet) natively supported by Apache Commons Net library, but it's not difficult to implement it.
如何做到这一点,如我对以下内容的回答所示:
如何使用相同的 TLS 会话通过数据连接连接到 FTPS 服务器?
How to do that, is shown in my answer to:
How to connect to FTPS server with data connection using same TLS session?
这篇关于当使用 Java Apache FTPClient 进行 FTP TLS 获取“握手期间远程主机关闭连接"时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!