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

原文地址:https://www.cnblogs.com/zys-blog/p/9454589.html

时间: 2024-10-30 00:46:41

FTPClient TLS 与 FTP 进行数据传输异常:Remote host closed connection during handshake的相关文章

实战2 Cacti监控Localhost和Remote Host

上篇博文主要讲解了cacti监控host主机,由于上篇博文cacti的版本也不是最新的!所以在实战2更新了cacti的版本,并添加了监控远程服务器和优化轮询 实战2 重点 一.新版cacti监控host 二.新版cacti监控Remote Host 三.新版cacti优化spine轮询 附加 四.网卡流量和存储挂在盘 一.新版cacti监控host 1.安装lamp平台 [[email protected] ~]# yum install -y httpd php php-mysql php-s

使用WebStorm/Phpstorm实现remote host远程开发

如果你的开发环境是在远程主机上,webstorm可以提供通过ftp/ftps/sftp等方式实现远程同步开发.这样我们可以就抛弃ftp.winscp等工具,通过webstorm编辑远程文件以及部署,本文基于WebStorm5.04编写, Intellij IDEA或者PHPStorm使用方法基本相同,可参考之.并且还要感谢因特里基友群群主大猫的帮助. 1.首先我们来创建一个基于远程主机的project,点击file>new project from existing sources,打开了创建p

scp不可用:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! After doing ssh are you seeing this error.No problem it can be solved. [email protected]:/tmp# ssh 10.10.0.16 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFI

ssh ip "WARING:REMOTE HOST IDENTIFICATION HAS CHANGED!"

[[email protected] network-scripts]# ssh 192.168.1.10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOM

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED

原文地址:http://linuxme.blog.51cto.com/1850814/375752 今天将阿里云服务器更换了一下系统盘,重启成功后,再次通过终端访问阿里云的公网IP报以下信息: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Linux:SSH错误"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! "

[email protected]:~$ scp /home/hadoop/.ssh/authorized_keys node3:/home/hadoop/.ssh/ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

SSH登录报错REMOTE HOST IDENTIFICATION HAS CHANGED!

ssh登录远程主机报错: [XX@XX ~]$ ssh monitor@xxx.xxx.xxx.xxx @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEO

SSH不能连接并提示REMOTE HOST IDENTIFICATION HAS CHANGED解决

SSH不能连接并提示REMOTE HOST IDENTIFICATION HAS CHANGED解决方法: 如果提示信息如下: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @    WARNING: REMOTE HOST IDENTIFICATION HASCHANGED!     @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS P

sftp修改用户home目录后登录时报connection closed by remote host

在sftp用户需要修改登录根目录的情况下,我们可以修改/etc/ssh/sshd_config文件中ChrootDirectory /home/[path]的路径. 但是,在重启sshd服务后,sftp登录报错connection closed by remote host 原因是 目录权限设置上要遵循2点: ChrootDirectory设置的目录权限及其所有的上级文件夹权限,属主和属组必须是root: ChrootDirectory设置的目录权限及其所有的上级文件夹权限,只有属主能拥有写权限