1. 程式人生 > >在java中使用SFTP協議安全的傳輸檔案

在java中使用SFTP協議安全的傳輸檔案

![file](https://img2020.cnblogs.com/other/1815316/202010/1815316-20201012071227672-1051132907.jpg) 本文介紹在Java中如何使用基於SSH的檔案傳輸協議(SFTP)將檔案從本地上傳到遠端伺服器,或者將檔案在兩個伺服器之間安全的傳輸。我們先來了解一下這幾個協議 * SSH 是較可靠,專為遠端登入會話和其他網路服務提供安全性的協議。比如:我們購買的雲伺服器登陸的時候使用的協議都是ssh。 * ftp協議通常是用來在兩個伺服器之間傳輸檔案的,但是它本質上是不安全的。 * 那麼SFTP是什麼?SFTP可以理解為SSH + FTP,也就是**安全的**網路檔案傳輸協議。 一般來說,SFTP和FTP服務都是使用相應的客戶端軟體來提供服務。如果你希望在java程式碼中使用SFTP協議進行安全的檔案傳輸,那麼這篇文章非常適合你。 ## 1. 匯入JSch 依賴包 在maven專案pom.xml中匯入如下的座標,我們使用JSch,JSch將SFTP協議封裝為對應的API供我們呼叫。 ~~~markup ~~~ ## 2. 檔案傳輸 – JSch例子 ### 2.1 get與put方法 在中`JSch`,我們可以使用`put`和`get`在伺服器之間進行檔案傳輸。`put`方法用來將檔案從本地系統傳輸到遠端伺服器。 ~~~java channelSftp.put(localFile, remoteFile); ~~~ `get`方法將檔案從遠端伺服器下載到本地系統。 ~~~java channelSftp.get(remoteFile, localFile); ~~~ ### 2.2 使用使用者名稱和密碼進行認證 ~~~java 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` ~~~java 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密碼登陸方式進行身份驗證。 ~~~java 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`檔案中。 ~~~bash $ ssh-keyscan -t rsa 1.2.3.4 >> ~/.ssh/known_hosts ~~~ ### 3.2對於私鑰無效異常 有可能是遠端伺服器重新生成了私鑰,需要把私鑰分發複製到本地伺服器。 ~~~bash 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) ~~~ ## 歡迎關注我的部落格,裡面有很多精品合集 * 本文轉載註明出處(必須帶連線,不能只轉文字):[字母哥部落格](http://www.zimug.com)。 **覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力!** 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。 * [《手摸手教你學Spring Boot2.0》]( https://www.kancloud.cn/hanxt/springboot2/content ) * [《Spring Security-JWT-OAuth2一本通》](https://www.kancloud.cn/hanxt/springsecurity/content) * [《實戰前後端分離RBAC許可權管理系統》](https://www.kancloud.cn/hanxt/vue-spring/content) * [《實戰SpringCloud微服務從青銅到王者》](https://www.kancloud.cn/hanxt/springcloud/content) * [《VUE深入淺出系列》](https://www.kancloud.cn/hanxt/vuejs2/