简体   繁体   English

在客户端上使用ftp4j忽略CentOS上的自签名ssl证书

[英]Ignore self-signed ssl cert on CentOS using ftp4j on client

Task: Connect to a CentOS box using FTP4J FTP using a self signed certificate. 任务:使用自签名证书使用FTP4J FTP连接到CentOS盒。

I am able to successfully connect to the CentOS box over FTP using 我能够使用以下命令通过FTP成功连接到CentOS盒

org.apache.commons.net.ftp.FTPSClient

however I receive the following error, which I know to be from the self signed certificate, using FTP4J. 但是我收到以下错误,该错误是使用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

A related question here on SO asked a similar question, just with a Jersey Client. SO上的一个相关问题也与泽西岛客户提出了类似的问题。 The answer there (cleaned up below, as the accepted answer yields a compiler error) does not work. 那里的答案(在下面进行清理,因为可接受的答案会产生编译器错误)不起作用。

Here is the FTP4J code with the trust all certs code, which does not work. 这是带有信任所有证书代码的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();
}

The Apache FTPSClient code connects flawlessly, just has trouble doing uploads, hence the FTP4J code now. 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();
}

I did peruse other questions, but could not find something that worked. 我确实细读了其他问题,但找不到有效的方法。 Any thoughts on how to tell FTP4J to ignore errors on self-signed certificates? 关于如何告诉FTP4J忽略自签名证书中的错误有任何想法吗?

You are so close. 你好亲近 First of all, get rid of the reference to HttpsURLConnection . 首先,摆脱对HttpsURLConnection的引用。 Has absolutely nothing to do with FTP or FTPS. 与FTP或FTPS完全无关。

But keep the TrustManager and SSLContext stuff, with just one minor change.... direct your FTPClient to use the resultant SSLSocketFactory . 但是,请保留TrustManagerSSLContext内容,只做一个小的更改。...指示FTPClient使用生成的SSLSocketFactory

So your final result looks something like this: 因此,您的最终结果如下所示:

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());

My source? 我的来源? The FTP4J manual . FTP4J手册 (I do note that that example there uses "SSL" instead of "TLS"; you may have to try it both ways.) (我确实注意到,该示例使用“ SSL”而不是“ TLS”;您可能必须同时尝试两种方法。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM