我需要在通过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,所以我不认为他们知道或关心这个,所以我决定将其从验证中删除。
答案 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);
}