【问题标题】:Ignore self-signed ssl cert on CentOS using ftp4j on client在客户端使用 ftp4j 忽略 CentOS 上的自签名 ssl 证书
【发布时间】:2016-04-09 13:34:29
【问题描述】:

任务:使用自签名证书的 FTP4J FTP 连接到 CentOS 机器。

我能够使用 FTP 成功连接到 CentOS 机器

org.apache.commons.net.ftp.FTPSClient

但是我收到以下错误,我知道这是来自使用 FTP4J 的自签名证书。

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

related question 在 SO 上问了一个类似的问题,只是针对 Jersey 客户。那里的答案(在下面清理,因为接受的答案会产生编译器错误)不起作用。

这是带有信任所有证书代码的 FTP4J 代码,它不起作用。

import java.io.IOException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.FTPDataTransferListener;
import it.sauronsoftware.ftp4j.FTPException;
import it.sauronsoftware.ftp4j.FTPIllegalReplyException;

FTPClient ftpsClient = new FTPClient();
try
{
    // Initialize the transfer information.
    this.oFtpArgs.oFtp.transferCount = this.oFtpArgs.pathFiles.size();
    this.oFtpArgs.oFtp.transferCompleted = 0;
    this.oFtpArgs.oFtp.filePercentComplete = 0L;
    this.oFtpArgs.oFtp.bytesTransferredTotal = 0L;

    // Connect to the server using active mode enabling FTP over explicit TLS/SSL (FTPES).
    ftpsClient.setSecurity(FTPClient.SECURITY_FTPES);
    ftpsClient.setPassive(false);
    ftpsClient.connect(this.oFtpArgs.serverIp, port);

    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager()
    {
        @Override
        public X509Certificate[] getAcceptedIssuers(){return null;}
        @Override
        public void checkClientTrusted(X509Certificate[] certs, String authType){}
        @Override
        public void checkServerTrusted(X509Certificate[] certs, String authType){}
    }};

    // Install the all-trusting trust manager
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, trustAllCerts, new SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

    // Log into the server.
    ftpsClient.login(user, pass);
}

catch (IOException ex)
{
    System.out.println("Error: " + ex.getMessage());
    ex.printStackTrace();
}

catch (Exception ex)
{
    System.out.println("Error: " + ex.getMessage());
    ex.printStackTrace();
}

Apache FTPSClient 代码完美连接,只是在上传时遇到问题,因此现在使用 FTP4J 代码。

import java.io.IOException;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;

FTPSClient ftpsClient = new FTPSClient("TLS", false);
try
{
    FTPClientConfig ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
    ftpsClient.configure(ftpClientConfig);
    ftpsClient.connect(this.oFtpArgs.serverIp, port);
    int ftpReplyCode = ftpsClient.getReplyCode();
    if (!FTPReply.isPositiveCompletion(ftpReplyCode))
        return;

    // Set protection buffer size
    ftpsClient.execPBSZ(0);

    // Set data channel protection to private
    ftpsClient.execPROT("P");

    // Log into the server.
    ftpsClient.login(user, pass);
    ftpReplyCode = ftpsClient.getReplyCode();
    if (!FTPReply.isPositiveCompletion(ftpReplyCode))
        return;

    // Enter local active mode .
    ftpsClient.enterLocalActiveMode();
}

catch (IOException ex)
{
    System.out.println("Error: " + ex.getMessage());
    ex.printStackTrace();
}

我确实仔细阅读了其他问题,但找不到有用的东西。关于如何告诉 FTP4J 忽略自签名证书上的错误有什么想法吗?

【问题讨论】:

    标签: java apache ssl ftp ftp4j


    【解决方案1】:

    你离得很近。首先,去掉对HttpsURLConnection的引用。与 FTP 或 FTPS 完全无关。

    但请保留 TrustManagerSSLContext 的内容,只需进行一点小改动.... 指示您的 FTPClient 使用生成的 SSLSocketFactory

    所以你的最终结果看起来像这样:

    TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager()
    {
        @Override
        public X509Certificate[] getAcceptedIssuers(){return null;}
        @Override
        public void checkClientTrusted(X509Certificate[] certs, String authType){}
        @Override
        public void checkServerTrusted(X509Certificate[] certs, String authType){}
    }};
    
    // Install the all-trusting trust manager
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, trustAllCerts, new SecureRandom());
    ftpsClient.setSSLSocketFactory(sc.getSocketFactory());
    

    我的来源? The FTP4J manual。 (我确实注意到该示例使用“SSL”而不是“TLS”;您可能必须尝试两种方式。)

    【讨论】:

    • 你不是在开玩笑,因为我很亲密。谢谢你。我漏掉了一行ftpsClient.setSSLSocketFactory(sc.getSocketFactory());,还有一条无关的行。
    猜你喜欢
    • 2011-08-28
    • 2017-02-13
    • 1970-01-01
    • 2021-04-07
    • 2011-05-24
    • 1970-01-01
    • 2016-10-01
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多