【问题标题】:Java FTPS disabling Certificate CheckJava FTPS 禁用证书检查
【发布时间】:2018-11-11 12:11:37
【问题描述】:

通过 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,所以我认为他们不知道也不关心这一点,所以我决定将其从验证中删除。

【问题讨论】:

  • 如果他们不使用 SSL,为什么不使用 FTP 而不是 FTPS?
  • 我最好的选择是可以禁用 FTP xD
  • 在这方面不太确定,他们是客户,并且对这些类型的知识有限,我不能真的建议他们只使用 ftp

标签: java ssl ftps


【解决方案1】:

这通常发生在服务器接受 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

以上四个是建立连接所需的常用配置。 最后的sn-p看起来是这样的

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

【讨论】:

  • 完全禁用证书检查是错误的。您仍然应该检查证书是否是您知道/期望的证书。不盲目接受任何。这样你就失去了对MITM attacks 的保护。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
  • 2017-02-03
  • 2013-09-07
  • 2019-03-03
  • 2018-07-12
  • 2013-10-20
  • 2016-11-13
相关资源
最近更新 更多