我试图连接到需要显式FTP在TLS的FTP。我正试图从我的本地机器上做这件事。
下面是我使用的代码
FTPSClient ftpClient = new FTPSClient(false);
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
ftpClient.setAuthValue("TLS");
ftpClient.connect(host, port);
int reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
if (ftpClient.login(username, password)) {
ftpClient.execPBSZ(0);
ftpClient.execPROT("P");
ftpClient.enterLocalPassiveMode();
InputStream is = new FileInputStream(localFilename);
if (ftpClient.storeFile(remoteFilename, is)) {
is.close();
} else {
System.out.println("Could not store file");
}
ftpClient.logout();
} else {
System.out.println("FTP login failed");
}
// Disconnect
ftpClient.disconnect();
} else {
System.out.println("FTP connect to host failed");
}
当我跑的时候,我得到下面的异常
Could not connect to server.
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
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:240)
at org.apache.commons.net.ftp.FTPSClient._connectAction_(FTPSClient.java:171)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:178)
at TestFTP.main(TestFTP.java:64)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(Unknown Source)
... 8 more
下面是我从Java CommandListener获得的日志
220-FileZilla Server 0.9.60 beta
220-written by Tim Kosse (tim.kosse@filezilla-project.org)
220 Please visit https://filezilla-project.org/
AUTH TLS
234 Using authentication type TLS
FTP client received network error javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
下面是我尝试使用FileZilla连接时的日志。它连接良好,我可以传输文件。但是当我尝试使用Java时,它没有连接
Response: 220-FileZilla Server 0.9.60 beta
Response: 220-written by Tim Kosse (tim.kosse@filezilla-project.org)
Response: 220 Please visit https://filezilla-project.org/
Command: AUTH TLS
Response: 234 Using authentication type TLS
Status: Initializing TLS...
Status: Verifying certificate...
Command: USER
Status: TLS/SSL connection established.
Response: 331 Password required
Command: PASS xxxx
Response: 230 Logged on
Command: PBSZ 0
Response: 200 PBSZ=0
Command: PROT P
Response: 200 Protection level set to P
Status: Connected
Status: Retrieving directory listing...
Command: PWD
Response: 257 "/" is current directory.
Command: TYPE I
Response: 200 Type set to I
Command: PASV
Response: 227 Entering Passive Mode ()
Command: MLSD
Response: 150 Opening data channel for directory listing of "/"
Response: 226 Successfully transferred "/"
Status: Directory listing successful
Status: Retrieving directory listing...
Command: PASV
Response: 227 Entering Passive Mode ()
Command: MLSD
Response: 150 Opening data channel for directory listing of "/"
Response: 226 Successfully transferred "/"
Status: Directory listing successful
你们能帮忙吗?
亲切的问候乔恩
我使用Cyberduck库解决了这个问题。https://github.com/iterate-ch/cyberduck
首先,为什么会出现这种握手问题,因为某些先进的FTP服务器只允许一个会话进行连接和数据传输。
1) 控制会话-
那么如何解决这个呢?
步骤1-:
首先,您需要从GitHub签出cyberduck回购协议。从这里开始-:https://github.com/iterate-ch/cyberduck
第2步-:您将看到FTP和核心模块在签出回购ftp和核心模块
步骤3-:将此模块转换为maven并为其创建jar。
步骤4-:将这个jar添加到您的项目中,但是这个jar还需要其他依赖项,因此也相应地将这些依赖项添加到项目构建路径中。
步骤5-:代码片段。
public class TestFTPS {
public static void main(String[] args) throws SocketException, IOException {
TrustManager[] trustManagers = new TrustManager[] { new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// TODO Auto-generated method stub
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// TODO Auto-generated method stub
}
} };
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new SecureRandom());
} catch (Exception e) {
e.printStackTrace();
}
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
Protocol protocol = new FTPTLSProtocol();
FTPClient client = new FTPClient(protocol, sslSocketFactory, sslContext);
client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
client.connect(ftphostname, port);
client.execAUTH("TLS"); //SSL
System.out.println(client.getReplyCode());
if (client.login(username, password)) {
client.execPBSZ(0);
client.execPROT("P");
String date = "Testing Data Send to provide FTP location";
client.setFileType(FTP.BINARY_FILE_TYPE);
client.enterLocalPassiveMode();
InputStream is = new ByteArrayInputStream(date.getBytes());
client.storeFile("test.txt", is);
System.out.print(client.getReplyCode());
}
}
}
步骤6-:运行此代码后,您的文件将成功传输到ftp位置。
注意-:请在您的项目中添加所需的jar
希望这对你有帮助。
该解决方案简单,技术上有点棘手,因为假设SSL会话(在其中打开连接)也应用于数据,但在FTPS的情况下,库会尝试会话外尝试数据,处理此操作的方法未在FTPS类中定义。因此,解决方案是简单地扩展FTPS类并为该方法提供实现。
这里有一个例子
public class ModifiedFTPSClient extends FTPSClient {
public ModifiedFTPSClient() {
super("TLS", false);
}
public ModifiedFTPSClient(boolean isImplicit) {
super("TLS", isImplicit);
}
@Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if (socket instanceof SSLSocket) {
final SSLSession session = ((SSLSocket) _socket_).getSession();
if (session.isValid()) {
final SSLSessionContext context = session.getSessionContext();
try {
final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method method = cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
method.setAccessible(true);
method.invoke(cache, String
.format("%s:%s", socket.getInetAddress().getHostName(), String.valueOf(socket.getPort()))
.toLowerCase(Locale.ROOT), session);
method.invoke(cache, String
.format("%s:%s", socket.getInetAddress().getHostAddress(), String.valueOf(socket.getPort()))
.toLowerCase(Locale.ROOT), session);
} catch (NoSuchFieldException e) {
throw new IOException(e);
} catch (Exception e) {
throw new IOException(e);
}
} else {
throw new IOException("Invalid SSL Session");
}
}
}}
现在,如果我尝试使用扩展类,它将在同一个会话中运行。即
ModifiedFTPSClient ftpClient = new ModifiedFTPSClient(true);
ftpClient.addProtocolCommandListener(new PrintCommandListener(System.out));
ftpClient.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager());... and so on.
首先,确保连接到FTP服务器的普通端口,因为您正在FTPS explict模式下实例化FTPSClient。
您使用的Java 7在更新75之前仍然使用SSLv2Hello来启动SSL会话。在过去几年中,在SSL中发现了Heartbleed、BEAST和所有其他漏洞之后,现在大多数基于SSL的服务器都拒绝使用版本为的TLS数据包进行握手尝试
判断我是否正确的最简单方法是尝试使用Java8启动应用程序(已切换到TLS1.2)。如果成功,您需要确保停用SSLv2Hello。这可以通过使用以下系统属性调用JVM全局完成:
java -Dhttps.protocols="TLSv1,TLSv1.1,TLSv1.2" -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" <MyApp>
或者在进行握手之前,在套接字上设置允许的协议,如下所示:
sslSocket.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"});
或者将相应的SSLSocketFactory
设置到FTPClient
以在FTPClient
需要SSLSocket
时设置如上所示的协议。我不知道Apache的FTPClient
,所以我无法告诉您如何做到这一点,但文档或谷歌搜索应该可以帮助您做到这一点。
但无论如何,停用SSLv2Hello是一件好事[TM],因此将JVM更新到最新版本(无论是Java 7 Update 80还是Java 8 Update 161)都不是一个坏主意,同时也可以获得所有其他与SSL无关的修复。
如果我关于SSLv2Hello的理论不正确,那么下一步唯一能帮助您解决这个问题的就是使用像Wireshark这样的TCP记录器,它可以向您显示实际的SSL握手以及对等服务器在什么时候关闭连接。通常,您可以在该跟踪中看到一个SSL警报,解释Java中收到的异常中未显示的实际问题。
感谢您抽出时间阅读我的问题-我正在使用EclipseIDE。我希望Jsoup连接https url-https://www.icegate.gov.in/使用 但它在线程“main”javax中给出了错误,而当我对其他https(如linkedin)使用相同的代码时,它就工作了。。。我不知道如何解决这个问题。 我获得了该网站的证书,并安装在我的jre/lib/security文件夹中,但它对我也没
我正在尝试连接到SOAPendpoint。 使用上面的方法,我不断得到下面的错误 java.lang.Thread.run(未知来源)[na: 1.8。0_191]原因:com.sun.xml.messaging.saaj.SOAPExceptionImpl:消息发送失败com.sun.xml.messaging.saaj.client.p2p。HttpSOAPConnection.post(Ht
我们为特定的IP地址配置了一个大型F5负载平衡器虚拟服务器,它将传入的https请求重定向到多个Windows服务器,在这些服务器上可以生成响应。 我正在使用SoapUI测试通过大F5中虚拟服务器的IP地址对这些windows服务器的访问。 使用由组织生成的服务器和客户机证书,我们在该组织中也进行了此设置,并通过SoapUI发送请求,我得到了预期的响应。 业务要求要求由Thawte签署商业证书。
SSLHandShakeException:尝试发布到以下URL时,在握手过程中发生远程主机关闭连接异常: https://testapi.title365.com/keystoneB2b/ordersservice.aspx 谁能帮帮忙吗?
我正在尝试连接到需要“通过TLS显式FTP”的FTP并上载文件。 我正在尝试从我的本地机器上实现它,它使用Java版本8和commons net FTP版本3.6 下面是我使用的代码 下面是我从Java CommandListener获得的日志 下面是我尝试使用FileZilla连接时的日志。连接很好,我可以传送文件。 但是,当我尝试使用Java时,它不会传输数据 请大家帮忙好吗? 亲切的问候乔恩
论坛上充斥着这个问题,但我找不到解决办法。我尝试连接WS,但没有成功。我试图更新cacerts文件,但没有效果。 日志是: 谢谢你的帮助