在java中使用SFTP协议安全的传输文件

Java中如何使用基于SSH的文件传输协议(SFTP)将文件从本地上传到远程服务器,或者将文件在两个服务器之间安全的传输。拉勾IT课小编带我们先来了解一下这几个协议,

SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议。比如:我们购买的云服务器登陆的时候使用的协议都是ssh。



  • ftp协议通常是用来在两个服务器之间传输文件的,但是它本质上是不安全的。
  • 那么SFTP是什么?SFTP可以理解为SSH + FTP,也就是安全的网络文件传输协议。

一般来说,SFTP和FTP服务都是使用相应的客户端软件来提供服务。如果你希望在java代码中使用SFTP协议进行安全的文件传输,那么这篇文章非常适合你。

1. 导入JSch 依赖包

在maven项目pom.xml中导入如下的坐标,我们使用JSch,JSch将SFTP协议封装为对应的API供我们调用。

<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>

2. 文件传输 – JSch例子

2.1 get与put方法

在中JSch,我们可以使用put和get在服务器之间进行文件传输。put方法用来将文件从本地系统传输到远程服务器。

channelSftp.put(localFile, remoteFile);

get方法将文件从远程服务器下载到本地系统。

channelSftp.get(remoteFile, localFile);

2.2 使用用户名和密码进行认证



JSch jsch = new JSch();
jsch.setKnownHosts("/home/zimug/.ssh/known_hosts");
jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
 
jschSession.setPassword(PASSWORD);
  • "/home/zimug/.ssh/known_hosts"为SSH的known_hosts文件,也就是可信远程主机的公钥保存文件。
  • USERNAME 为用户名
  • REMOTE_HOST远程主机的Ip
  • REMOTE_PORT远程主机端口
  • PASSWORD远程主机登录密码

2.3.使用公钥和私钥进行认证

如果读者不能理解公钥和私钥的用法及含义,需要先自行补充一下SSH知识。

  • 本地私钥–/home/登录用户名/.ssh/id_rsa
  • 远程公钥默认保存位置–~/.ssh/authorized_keys

JSch jsch = new JSch();
jsch.setKnownHosts("/home/zimug/.ssh/known_hosts");
jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
 
jsch.addIdentity("/home/zimug/.ssh/id_rsa");

2.4 完整JSch文件传输示例

将文件从本地系统传输到远程服务器1.2.3.4,并使用SSH密码登陆方式进行身份验证。

import com.jcraft.jsch.*;
 
public class SFTPFileTransfer {
 
    private static final String REMOTE_HOST = "1.2.3.4";  //远程主机ip
    private static final String USERNAME = "";  //登录用户名
    private static final String PASSWORD = "";  //登陆密码
    private static final int REMOTE_PORT = 22;   //ssh协议默认端口
    private static final int SESSION_TIMEOUT = 10000; //session超时时间
    private static final int CHANNEL_TIMEOUT = 5000; //管道流超时时间
 
    public static void main(String[] args) {
 
        String localFile = "/home/zimug/local/random.txt";   //本地文件路径
        String remoteFile = "/home/zimug/remote/targetfile.txt";   //上传到远程的文件路径,要保证登录用户有写权限
 
        Session jschSession = null;
 
        try {
 
            JSch jsch = new JSch();
            jsch.setKnownHosts("/home/zimug/.ssh/known_hosts");
            jschSession = jsch.getSession(USERNAME, REMOTE_HOST, REMOTE_PORT);
 
            // 通过ssh私钥的方式登录认证
            // jsch.addIdentity("/home/zimug/.ssh/id_rsa");
 
            // 通过密码的方式登录认证
            jschSession.setPassword(PASSWORD);
            jschSession.connect(SESSION_TIMEOUT);
 
            Channel sftp = jschSession.openChannel("sftp");  //建立sftp文件传输管道
            sftp.connect(CHANNEL_TIMEOUT);
 
            ChannelSftp channelSftp = (ChannelSftp) sftp;
 
            // 传输本地文件到远程主机
            channelSftp.put(localFile, remoteFile);
 
            channelSftp.exit();
 
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        } finally {
            if (jschSession != null) {
                jschSession.disconnect();
            }
        }
        System.out.println("文件传输完成!");
    }
}

3. JSch异常处理

在文件上传的过程中,我们可能会遇到下面的一些异常

3.1UnknownHostKey异常

需要将远程服务器IP地址添加到known_hosts文件中。

$ ssh-keyscan -t rsa 1.2.3.4 >> ~/.ssh/known_hosts

3.2对于私钥无效异常

有可能是远程服务器重新生成了私钥,需要把私钥分发复制到本地服务器。

ssh-copy-id  -i  ~/.ssh/id_rsa.pub  <被分发的服务器ip>

3.3对于Auth fail异常

请确保提供的登录密码时正确的

com.jcraft.jsch.JSchException: Auth fail
         at com.jcraft.jsch.Session.connect(Session.java:519)
         at com.zimug.io.howto.SFTPFileTransfer.main(SFTPFileTransfer.java:34)

相关文章

Java程序员需要具备哪些专业技能?

我们都知道,Java程序员是一个技术岗位,从技术上和业务上都需要不断地提升自我。经常有小伙伴疑惑:一个合格的Java程序员需要会哪些东西?今天,就来和大家好好聊一聊,超多干货,快快收藏哦! Java程...

Java 开发人员所需的技能

  Java 的潜力一直是许多公司的话题。 事实上,几乎每家公司都在使用 Java,无论是小公司还是一些大型科技巨头公司。另一方面,还有许多其他公司正在招聘 Java 开发人员。Java开发人员技能可...

【重磅】JAVA工程师入行秘籍:必备技能与未来发展趋势!

作为一种在全球范围内应用广泛的编程语言,Java以其稳定性、跨平台性和高性能等优势,成为了企业级应用开发的首选。而对于许多程序员来说,成为一名合格的Java工程师,无疑是进入软件开发行业的黄金通道。那...

经验 | Java工程师需要具备的25个技能

在Java工程师日常的开发过程中,由于业务的不同,可能关注的点有很多不一样的地方,但是在技术掌握层面还是有一些共性的。本文概括了在Java工程师开发、测试、部署等方面的25个必备技能,供大家参考。01...

一个高级Java工程师需要掌握哪些技能?

Java核心知识,包括集合类,IO/NIO,JVM,内存模型,泛型,异常,反射,多线程,锁,CAS,AQS等数据结构与算法,包括常见的排序,查找,树,图,堆,栈,队列,链表,哈希表等,以及一些经典的算...

Java基础知识有哪些 怎么不断提高专业技能

  Java基础知识有哪些?怎么不断提高专业技能?在学习Java的过程中,需要从基础知识慢慢理解,通过一点点的学习积累,能够不断懂得编程的概念。基础知识的学习非常重要,Java编程其实并不难学,难的是...