Perl用于Java的Net :: FTPSSL模拟或如何在Java中使用ftp over SSL

时间:2014-10-08 11:18:43

标签: java perl ssl ftp

我需要将代码从Perl迁移到Java。

我在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使用与Net :: FTPSSL相同的协议 - 基于SSL的FTP。那么我做错了什么?

2 个答案:

答案 0 :(得分: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盲目连接。

答案 1 :(得分: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);