When using Java Apache FTPClient for FTP TLS getting “Remote host closed connection during handshake” [duplicate]

匿名 (未验证) 提交于 2019-12-03 01:57:01

问题:

This question already has an answer here:

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(); 

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) 

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) 

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?

My ftp Object

回答1:

I have Solved this problem using Cyberduck library. https://github.com/iterate-ch/cyberduck
first why this Handshake problem arises, because some advances FTP servers allow only one session for connection and data transmission.

1)Control Session - > for connection
2)Data Session - > data storage/download/etc

So how to solve this.

Step 1 -:

First You need to checkout cyberduck repo from GitHub. from here - : https://github.com/iterate-ch/cyberduck

Step 2 -: You will see FTP and core module in checkout repo ftp and core modules

Step 3 -: Convert this module into maven and create jar for the same.

Step 4 -: add this jar into you project, but this jar also requires other dependencies so add those accordingly into project build path as well.

Step 5 -: Code snippet.

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());         }     } } 

Step 6 -: After running this code, your file will be transferred successfully to ftp location.

Note - :Please add required jar in your project

Hope This will help you.



回答2:

The important information is not the exception message itself, but this message in the log:

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

Some FTP servers to require that you reuse the TLS session for data connections.

This is not (yet) natively supported by Apache Commons Net library, but it's not difficult to implement it.

How to do that, is shown in my answer to:
How to connect to FTPS server with data connection using same TLS session?



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!