美文网首页
在java中使用SFTP协议安全的传输文件

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

作者: 字母哥课堂 | 来源:发表于2020-10-12 07:12 被阅读0次
    file

    本文介绍在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)
    

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

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

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

    相关文章

      网友评论

          本文标题:在java中使用SFTP协议安全的传输文件

          本文链接:https://www.haomeiwen.com/subject/adxupktx.html