FTP client received network error javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

梦想的初衷 提交于 2019-12-24 22:16:29

问题


I am trying to connect to FTP that requires 'Explicit FTP over TLS' and upload a file.

I am trying to do it from my local machine which uses Java version 8 and commons net FTP version 3.6

Below is the code which I use

          try {

              FTPSClient ftpClient = new FTPSClient();


              ftpClient.setDataTimeout(300); 
              ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
              ftpClient.setAuthValue("TLS");
              ftpClient.connect(server, port);
              int reply = ftpClient.getReplyCode();


              if (FTPReply.isPositiveCompletion(reply)) {
                  ftpClient.execAUTH("TLS"); //SSL


                // Login
                if (ftpClient.login(user, pass)) {

                  // Set protection buffer size
                  ftpClient.execPBSZ(0);
                  // Set data channel protection to private
                  ftpClient.execPROT("P");
                  // Enter local passive mode
                  ftpClient.enterLocalPassiveMode();
                  ftpClient.changeWorkingDirectory("/");
                  ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
              File firstLocalFile = new File(outputFileNameCSV);
                              String firstRemoteFile = csvFileNameOut;
                  InputStream inputStream = new FileInputStream(firstLocalFile);

                  // Store file on host
                  boolean done = ftpClient.storeFile(firstRemoteFile, inputStream);
              inputStream.close();
              if (done) 
              {
                System.out.println("The file is uploaded successfully.");
              }

              // Logout
              ftpClient.logout();

                } else {
                  System.out.println("FTP login failed");
                }

                // Disconnect
                ftpClient.disconnect();

              } else {
                System.out.println("FTP connect to host failed");
              }
            } catch (IOException ioe) {
              System.out.println("FTP client received network error "+ioe);
            }

Below is the log I get from Java CommandListener

220-FileZilla Server 0.9.60 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
AUTH TLS
534 Authentication type already set to TLS
FTP login screen
USER test
331 Password required for test
PASS pass
230 Logged on
PBSZ 0
200 PBSZ=0
PROT P
200 Protection level set to P
CWD /
250 CWD successful. "/" is current directory.
TYPE I
200 Type set to I
PASV
227 Entering Passive Mode ()
STOR file.csv
150 Opening data channel for file upload to server of "/file.csv"
FTP client received network error javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

Below is the log when I try to connect using FileZilla. It is connecting fine and I can transfer the files.

But when I try using Java, it isn't transferring

Response:   220-FileZilla Server 0.9.60 beta
Response:   220-written by Tim Kosse (tim.kosse@filezilla-project.org)
Response:   220 Please visit https://filezilla-project.org/
Command:    AUTH TLS
Response:   234 Using authentication type TLS
Status: Initializing TLS...
Status: Verifying certificate...
Command:    USER test
Status: TLS/SSL connection established.
Response:   331 Password required for test
Command:    PASS pass
Response:   230 Logged on
Command:    PBSZ 0
Response:   200 PBSZ=0
Command:    PROT P
Response:   200 Protection level set to P
Status: Connected
Status: Starting upload of file.csv
Command:    CWD /
Response:   250 CWD successful. "/" is current directory.
Command:    TYPE I
Response:   200 Type set to I
Command:    PASV
Response:   227 Entering Passive Mode ()
Command:    STOR file.csv
Response:   150 Opening data channel for file upload to server of "/file.csv"
Response:   226 Successfully transferred "/file.csv"
Status: File transfer successful, transferred 12,252 bytes in 1 second

Could you all please help?

Kind regards Jon


回答1:


Modern FTP servers expect the data channel to be opened by using TLS session resume. Java is capable of doing this but only for connections to the same IP and port. Because the data channel of an FTP session uses a different port the mechanism fails, so you need to force the JVM to do that and includes quite heavy fiddling with the interns of java classes using reflection.

You're using the Apache FTPSClient, so you might check if a more recent version of it already does that for you but if it's still not done, you might do it yourself as it is described in a Blog post on Wealthfront.

The hack (I still fail it to call it differently) works well with clients but there is some significant additional work to be done if you want to do this on a server side (i.e. if you want to implement you own FTP server). Your question doesn't look like it, so I spare this part in this answer.



来源:https://stackoverflow.com/questions/49012248/ftp-client-received-network-error-javax-net-ssl-sslhandshakeexception-remote-ho

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