【问题标题】:Perl's Net::FTPSSL analogue for Java or how to use ftp over SSL in JavaPerl 的 Net::FTPSSL 模拟 Java 或如何在 Java 中使用 ftp over SSL
【发布时间】:2014-10-08 11:18:43
【问题描述】:

我需要将代码从 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 - FTP over SSL 相同的协议。那我做错了什么?

【问题讨论】:

    标签: java perl ssl ftp


    【解决方案1】:

    据我了解,FTPSClient 使用与 Net::FTPSSL - FTP over SSL 相同的协议。

    Net::FTPSSL 默认不验证证书(因此对中间人攻击开放)。 FTPSClient 会验证证书并发出警告,因为证书已在 2008 年过期:“CertificateExpiredException: NotAfter: Fri Dec 19 15:47:22 EET 2008”。

    据我了解,FTPSClient 使用与 Net::FTPSSL - FTP over SSL 相同的协议。

    您尝试使用无效(因为已过期)证书连接​​到站点。 FTPSClient 正确拒绝连接,而 Net::FTPSSL 盲目连接。

    【讨论】:

    • 谢谢。能否请您告诉我如何使用 FTPSClient 在没有证书的情况下进行连接(我知道这是不安全的)?
    • 我没有使用 FTPSClient 的经验,但从文档看来您必须添加自己的 TrustManager,所以也许只需搜索信任所有证书的 TrustManager。但请注意,通过不验证证书,您允许中间人攻击,从而破坏了使用 FTPS 而不是未加密 FTP 的主要目的。也许你应该寻找一个验证证书指纹的 TrustManager,这样你至少可以确定你连接到一个特定的证书,即使它已经过期了。
    • 我知道不经验证就使用 FTPS 是不合适的,但我必须迁移现有代码,它使用 Net::FTPSSL 未经验证。但我会考虑验证。
    【解决方案2】:

    此代码运行良好。但正如@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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 2023-04-04
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多