FTPClient TLS 与 FTP 进行数据传输异常:Remote host closed connection during handshake
环境:java JDK 1.8、org.apache.commons-net-3.6.jar、端口已放开
FTPClient ftpClient = new FTPClient(protocol, false);
ftpClient.setRemoteVerificationEnable(false);
ftpClient.setControlKeepAliveTimeout(300);
ftpClient.setDataTimeout(300);
InputStream fin = null;
try {
ftpClient.connect(host, port);
int reply = ftpClient.getReplyCode();
if (ftpClient.isPositiveComletion(reply)) {
if (ftpClient.login(username, password)) {
ftpClient.feat();
ftpClient.execPBSZ(0);
ftpClient.execPROT("p");
ftpClient.setControlEncoding("UTF-8");
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
try {
fin = new FileInoutStream(new File("C:\\doc_home\\test1.txt"));
} catch (FileNotFoundException e) {
System.out.println("---file not found");
}
String remoteFile = "test1.txt";
ftpClient.mlsd();
if (ftpClient.storeFile(remoteFile, fin)) {
fin.close();
} else {
System.out.println("could not store file");
}
fin.close();
} else {
System.out.println("FTP login failed");
}
} else {
System.out.println("FTP connect to host failed");
}
} catch (IOException ioe) {
ioe.printStackTrace();
System.out.println("FTP client received network error");
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException ioe) {
//do nothing
}
}
}
异常:
javax.net.ssl.SSLHandshakeException:Remote host closed connection during handshake
FTP client received network error
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.openDataConnection(FTPClient.java:646)
at org.apache.commons.net.ftp.FTPSClient.storeFile(FTPClient.java:653)
at org.apache.commons.net.ftp.FTPSClient.storeFile(FTPClient.java:2030)
at ibgdashboardtest.Demo4.main(Demo4.java:75)
Caused by:java.io.EOFException:SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(Unknown Source)
... 9 more
解决方法:自己定义一个类继承FTPSClient,重载_prepareDataSocket_(final Socket socket)方法,添加了TLS的session hash支持并扩展了密钥,使用时用该类来替代FTPSClient的使用
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Locale;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import org.apache.commons.net.ftp.FTPSClient;
public class SSLSessionReuseFTPSClient extends FTPSClient {
// adapted from:
// https://trac.cyberduck.io/browser/trunk/ftp/src/main/java/ch/cyberduck/core/ftp/FTPClient.java
@Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if (socket instanceof SSLSocket) {
// Control socket is SSL
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");
}
}
}
}
如果出现兼容问题,应用程序可能会通过JDK中将系统设置属性jdk.tls.useExtendedMasterSecret设置为false来禁用此扩展,在JDK 1.8.0_161中设置:
System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
以上解决方法源自:https://stackoverflow.com/questions/32398754/how-to-connect-to-ftps-server-with-data-connection-using-same-tls-session
FTPClient TLS 与 FTP 进行数据传输异常:Remote host closed connection during handshake的更多相关文章
- javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
2019独角兽企业重金招聘Python工程师标准>>> 问题 前两天一个学弟在群里面问一个问题: 请问一下用阿里云服务器发送https请求为什么会失败,是需要有些其他什么配置吗? 同 ...
- Charles 抓包 Client SSL handshake failed - Remote host closed connection during handshake
Charles 抓包 https 报错: Client SSL handshake failed - Remote host closed connection during handshake # ...
- Bind 远程连接DNS服务器时出现 rndc: connection to remote host closed
使用命令:rndc -s 192.168.1.2 status 连接远程的bind 搭建的DNS服务器时出现下面的错误: rndc: connection to remote host close ...
- RemoteDisconnected: Remote end closed connection without response
- #python# error:http.client.RemoteDisconnected: Remote end closed connection without response
添加headers user-agent 网络情况不好的状态下也能出现
- ssh问题:ssh_exchange_identification: Connection closed by remote host
ssh问题:ssh_exchange_identification: Connection closed by remote host... 刚刚一个朋友告诉我SSH连接不上服务器了,重启电脑也不管用 ...
- TLS是如何保障数据传输安全(中间人攻击)
前言 前段时间和同事讨论HTTPS的工作原理,当时对这块知识原理掌握还是靠以前看了一些博客介绍,深度不够,正好我这位同事是密码学专业毕业的,结合他密码学角度对tls加解密这阐述,让我对这块原理有了更进 ...
- 关于ssh登录出现异常警告:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
提示警告信息如下: arnold@WSN:~$ ssh 10.18.46.111 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ...
- Mac和Linux远程连接服务器异常修复(WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!)
感谢大佬:https://blog.csdn.net/wd2014610/article/details/79945424 一.今天在使用SSH,连接远程服务器的时候,刚开始是没问题的. 后来阿里云主 ...
随机推荐
- python模块之numpy,pandas基本用法
numpy: 是 Python 的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库简单来说:就是支持一维数组和多维数组的创建和操作,并有丰富的函数库. 直接看例子 ...
- tuple unpacking
拆开Tuple lax_coordinates = (33.9425, -118.408056) latitude, longitude = lax_coordinates # tuple unpac ...
- Oracle 的trim,ltrim,rtrim函数的区别
该函数共有两种作用:第一种,即大家都比较熟悉的去除空格.例子:--TRIM去除指定字符的前后空格SQL> SELECT TRIM(' dd df ') FROM dual;TRIM('DDDF' ...
- Code Review怎样做好
一.背景 最近随着交易业务快速扩展,研发组内新项目及新成员越来越多,如何做好Code Review,把控研发人员开发代码质量很是关键. 对于大部分业务团队,谈到Code Review就会面露哀状: ...
- STM32 TIM3 PWM输出 4路
一.设置TIM3的GPIO为推挽输出 void TIM3_IOConfig(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClo ...
- div中粘贴图片并上传服务器 div中拖拽图片文件并上传服务器
应用简介:此文主要是描述如何在前端div中直接ctrl+v 粘贴图片,并上传到服务器,包括拖拽图片文件到div中 应用场景描述:用QQ或者其它切图软件截图,在指定的div中ctrl+v 粘贴并显示,点 ...
- Python基础教程(016)--Python2和Python3的介绍
前言 Python2和Python3的区别 内容 Python3是现在和未来的主要版本 Python3没有考虑向下兼容. 官方提供了一个Python过度版本Python2.6 Python2.6及支持 ...
- C#生成一个按时间排序的DUID
/// <summary> /// 创建一个按时间排序的Guid /// </summary> /// <returns></returns> publ ...
- asd的甩锅计划
asd的甩锅计划 时间限制: 1 Sec 内存限制: 128 MB提交: 177 解决: 19[提交][状态] 题目描述 大家对hdu上面的畅通工程系列一定很熟悉了吧.比如如下一段,就是畅通工程里 ...
- CSS-inline-block 间隙
间隙产生的原因是`inline-block`对外是`inline`,对内是`block`.`inline`会将连续的空白符解析为一个空格(如:下面示例的两个`li`之间的后面的换行空格).取消间隙的方 ...