Java FTPS禁用证书检查

时间:2018-06-01 10:57:54

标签: java ssl ftps

我需要在通过FTPS连接到站点时禁用证书检查。似乎连接正在寻找有效的证书,并且给定的证书已经过期。通过WINSCP,我们可以接受证书,尽管已过期,但java不会让我联系。

javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateExpiredExcept
ion: NotAfter: Fri Mar 31 00:00:00 SGT 2017
        at sun.security.ssl.Alerts.getSSLException(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
        at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
        at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
        at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
        at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
        at sun.security.ssl.Handshaker.processLoop(Unknown Source)
        at sun.security.ssl.Handshaker.process_record(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source
)
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at org.apache.commons.net.ftp.FTPSClient.sslNegotiation(FTPSClient.java:
289)
        at org.apache.commons.net.ftp.FTPSClient._connectAction_(FTPSClient.java
:220)
        at org.apache.commons.net.SocketClient._connect(SocketClient.java:244)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:202)
        at org.apache.commons.net.SocketClient.connect(SocketClient.java:306)
        at ftpsdownload.Main.downloadFiles(Main.java:68)
        at ftpsdownload.Main.main(Main.java:38)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoa
der.java:58)
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Fri Mar 31
00:00:00 SGT 2017
        at sun.security.x509.CertificateValidity.valid(Unknown Source)
        at sun.security.x509.X509CertImpl.checkValidity(Unknown Source)
        at sun.security.x509.X509CertImpl.checkValidity(Unknown Source)
        at org.apache.commons.net.util.TrustManagerUtils$TrustManager.checkServe
rTrusted(TrustManagerUtils.java:61)
        at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unkno
wn Source)
        ... 20 more

服务器管理员说他们没有使用SSL,所以我不认为他们知道或关心这个,所以我决定将其从验证中删除。

1 个答案:

答案 0 :(得分:0)

这通常发生在服务器接受 ftps 连接(不是 ftp 连接)时。 apache commons net 也支持 FTPS。使用下面的代码作为参考。

1) FTPS 服务器的加密将是 TLS 显式加密TLS 显式加密。相应地使用 FTPS 的构造函数 arg。喜欢

      FTPSClient ftpClient = new FTPSClient(false);

2) 如果您的 FTPS 服务器安全证书已过期,请通过以下方式禁用来自客户端的检查

ftpClient.setTrustManager(new X509TrustManager() {
    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] certs, String authType) {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] certs, String authType) {
    }
});

3) 使用此方法启用服务器和客户端之间的文件传输

    ftpClient.enterLocalPassiveMode();

4) 使用正确的端口号。通常显式加密为 21,隐式加密为 990

以上四个是建立连接所需的常用配置。 结束片段看起来像这样

FTPSClient ftpClient = new FTPSClient(false);
        ftpClient.setTrustManager(new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        });
        ftpClient.connect("ftps.mydomain.com",21);
        boolean res = ftpClient.login("username", "password");
        if(!res) throw new Exception("unable to connect to ftps");
        int reply=ftpClient.getReplyCode();
        if(FTPReply.isPositiveCompletion(reply)){
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles("/folder/subfolder");
            System.out.println("complete "+reply+" "+ftpFiles.length);
            for(FTPFile x: ftpFiles){
                System.out.println(x.getName());
            }
            ftpClient.retrieveFile("/folder/subfolder/file.tsv",new FileOutputStream(new File("C:\\Users\\myname\\Desktop\\out.csv")));
        }else{
            throw new RuntimeException("unable to get valid reply from ftp server. Reply code is "+reply);
        }