2014-10-08 50 views
0

我需要将代码从Perl迁移到Java。用于Java的Perl的Net :: FTPSSL模拟器或如何在Java中使用ftp over SSL

我有这样的代码在Perl:

use Net::FTPSSL; 

print "RUN\n"; 
my $ftpdebug = 0; 
my $ip   = "..."; 
my $port  = 2121; 
my $atmpassword = "..."; 
my $atmuser  = "..."; 

my $ftp = Net::FTPSSL->new($ip, Port => $port, Debug => $ftpdebug); 

if ($ftp) { 
    print "SUCCESS\n"; 
    $ftp->login($atmuser, $atmpassword); 
    print "LOGIN \n"; 
    @list = $ftp->list(); 
    for $i (@list) { 
     print $i . "\n"; 
    } 
} else { 
    print "FAIL\n"; 
} 

,它工作正常。它向我输出服务器上的文件列表。 但是,当我尝试使用相同的主机和端口在Java中执行此操作时,我甚至无法连接到服务器。 我想:

try { 
    FTPSClient ftpClient = new FTPSClient(false); 

    // Connect to host 
    ftpClient.connect(host, 2121); 
    int reply = ftpClient.getReplyCode(); 
    if (FTPReply.isPositiveCompletion(reply)) { 

     // Login 
     if (ftpClient.login(name, password)) { 

      // Set protection buffer size 
      ftpClient.execPBSZ(0); 
      // Set data channel protection to private 
      ftpClient.execPROT("P"); 
      // Enter local passive mode 
      ftpClient.enterLocalPassiveMode(); 
      log.info(ftpClient.printWorkingDirectory()); 
      // Logout 
      ftpClient.logout(); 

     } else { 
      log.info("FTP login failed"); 
     } 

     // Disconnect 
     ftpClient.disconnect(); 

    } else { 
     log.info("FTP connect to host failed: " + reply); 
    } 
} catch (IOException ioe) { 
    log.info("FTP client received network error"); 
    log.info(ioe.getMessage()); 
    ioe.printStackTrace(); 
} catch (NoSuchAlgorithmException nsae) { 
    log.info("FTP client could not use SSL algorithm"); 
} 

而且它在这条线失败:

ftpClient.connect(host, 2121); 

的误差修改为:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateExpiredException: NotAfter: Fri Dec 19 15:47:22 EET 2008 

据我了解FTPSClient使用相同的协议,网:: FTPSSL - 通过SSL的FTP。那么我做错了什么?

回答

3

正如我所了解的FTPSClient使用与Net :: FTPSSL相同的协议 - 基于SSL的FTP。

Net :: FTPSSL在默认情况下不验证证书(因此可用于中间人攻击)。 FTPSClient取而代之的是验证证书并咆哮,因为该证书在2008年已过期:“CertificateExpiredException:NotAfter:Fri Dec 19 15:47:22 EET 2008”。

正如我所了解的FTPSClient使用与Net :: FTPSSL相同的协议 - 基于SSL的FTP。

您尝试连接到具有无效(因为过期)证书的网站。 FTPSClient正确拒绝连接,而Net :: FTPSSL是盲目连接的。

+0

谢谢。您能否告诉我如何使用FTPSClient无证书连接(我知道这是不安全的)? – 2014-10-08 15:14:47

+0

我对FTPSClient没有经验,但是从文档看起来您必须添加自己的TrustManager,因此可能只需要搜索TrustManager来信任所有的证书。但请注意,通过不验证证书,您允许中间人攻击,从而打败了使用FTPS而不是未加密FTP的主要目的。也许你应该看看TrustManager验证证书指纹,这样至少可以确保你连接到特定的证书,即使证书已过期。 – 2014-10-08 18:03:46

+0

据我所知,使用FTPS无需验证是不合适的,但我必须迁移现有的代码,该代码使用Net :: FTPSSL而无需验证。但我会考虑验证。 – 2014-10-09 05:55:01

0

此代码正常工作。但正如@Steffen Ullrich所说的那样是不安全的。

 SSLContext sslContext = SSLContext.getInstance("SSL"); 
     TrustManager tm = new X509TrustManager() { 
      public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
      } 

      public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
      } 

      public X509Certificate[] getAcceptedIssuers() { 
       return null; 
      } 
     }; 
     sslContext.init(null, new TrustManager[] { tm }, null); 
     FTPSClient ftpClient = new FTPSClient(sslContext);