23

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

 3 years ago
source link: http://www.cnblogs.com/zimug/p/13800694.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

NVv6zyF.jpg!mobile

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

  • 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 ,我们可以使用 putget 在服务器之间进行文件传输。 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)

欢迎关注我的博客,里面有很多精品合集

  • 本文转载注明出处(必须带连接,不能只转文字): 字母哥博客

觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力!。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK