在java中使用SFTP協議安全的傳輸文件


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)

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

  • 本文轉載注明出處(必須帶連接,不能只轉文字):字母哥博客

覺得對您有幫助的話,幫我點贊、分享!您的支持是我不竭的創作動力! 。另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM