在java中使用SFTP協(xié)議安全的傳輸文件

file

本文介紹在Java中如何使用基于SSH的文件傳輸協(xié)議(SFTP)將文件從本地上傳到遠(yuǎn)程服務(wù)器,或者將文件在兩個服務(wù)器之間安全的傳輸。我們先來了解一下這幾個協(xié)議

  • SSH 是較可靠龙考,專為遠(yuǎn)程登錄會話和其他網(wǎng)絡(luò)服務(wù)提供安全性的協(xié)議箱硕。比如:我們購買的云服務(wù)器登陸的時候使用的協(xié)議都是ssh儿倒。
  • ftp協(xié)議通常是用來在兩個服務(wù)器之間傳輸文件的版保,但是它本質(zhì)上是不安全的呜笑。
  • 那么SFTP是什么夫否?SFTP可以理解為SSH + FTP彻犁,也就是安全的網(wǎng)絡(luò)文件傳輸協(xié)議。

一般來說凰慈,SFTP和FTP服務(wù)都是使用相應(yīng)的客戶端軟件來提供服務(wù)汞幢。如果你希望在java代碼中使用SFTP協(xié)議進(jìn)行安全的文件傳輸,那么這篇文章非常適合你微谓。

1. 導(dǎo)入JSch 依賴包

在maven項目pom.xml中導(dǎo)入如下的坐標(biāo)森篷,我們使用JSch,JSch將SFTP協(xié)議封裝為對應(yīng)的API供我們調(diào)用豺型。

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

2. 文件傳輸 – JSch例子

2.1 get與put方法

在中JSch仲智,我們可以使用putget在服務(wù)器之間進(jìn)行文件傳輸。put方法用來將文件從本地系統(tǒng)傳輸?shù)竭h(yuǎn)程服務(wù)器姻氨。

channelSftp.put(localFile, remoteFile);

get方法將文件從遠(yuǎn)程服務(wù)器下載到本地系統(tǒng)钓辆。

channelSftp.get(remoteFile, localFile);

2.2 使用用戶名和密碼進(jìn)行認(rèn)證

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文件,也就是可信遠(yuǎn)程主機的公鑰保存文件肴焊。
  • USERNAME 為用戶名
  • REMOTE_HOST遠(yuǎn)程主機的Ip
  • REMOTE_PORT遠(yuǎn)程主機端口
  • PASSWORD遠(yuǎn)程主機登錄密碼

2.3.使用公鑰和私鑰進(jìn)行認(rèn)證

如果讀者不能理解公鑰和私鑰的用法及含義前联,需要先自行補充一下SSH知識。

  • 本地私鑰–/home/登錄用戶名/.ssh/id_rsa
  • 遠(yuǎn)程公鑰默認(rèn)保存位置–~/.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文件傳輸示例

將文件從本地系統(tǒng)傳輸?shù)竭h(yuǎn)程服務(wù)器1.2.3.4娶眷,并使用SSH密碼登陸方式進(jìn)行身份驗證似嗤。

import com.jcraft.jsch.*;

public class SFTPFileTransfer {

    private static final String REMOTE_HOST = "1.2.3.4";  //遠(yuǎn)程主機ip
    private static final String USERNAME = "";  //登錄用戶名
    private static final String PASSWORD = "";  //登陸密碼
    private static final int REMOTE_PORT = 22;   //ssh協(xié)議默認(rèn)端口
    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";   //上傳到遠(yuǎn)程的文件路徑,要保證登錄用戶有寫權(quán)限

        Session jschSession = null;

        try {

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

            // 通過ssh私鑰的方式登錄認(rèn)證
            // jsch.addIdentity("/home/zimug/.ssh/id_rsa");

            // 通過密碼的方式登錄認(rèn)證
            jschSession.setPassword(PASSWORD);
            jschSession.connect(SESSION_TIMEOUT);

            Channel sftp = jschSession.openChannel("sftp");  //建立sftp文件傳輸管道
            sftp.connect(CHANNEL_TIMEOUT);

            ChannelSftp channelSftp = (ChannelSftp) sftp;

            // 傳輸本地文件到遠(yuǎn)程主機
            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異常

需要將遠(yuǎn)程服務(wù)器IP地址添加到known_hosts文件中。

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

3.2對于私鑰無效異常

有可能是遠(yuǎn)程服務(wù)器重新生成了私鑰豌注,需要把私鑰分發(fā)復(fù)制到本地服務(wù)器伤塌。

ssh-copy-id  -i  ~/.ssh/id_rsa.pub  <被分發(fā)的服務(wù)器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)

歡迎關(guān)注我的博客,里面有很多精品合集

  • 本文轉(zhuǎn)載注明出處(必須帶連接幌羞,不能只轉(zhuǎn)文字):字母哥博客寸谜。

覺得對您有幫助的話,幫我點贊属桦、分享熊痴!您的支持是我不竭的創(chuàng)作動力! 聂宾。另外果善,筆者最近一段時間輸出了如下的精品內(nèi)容,期待您的關(guān)注系谐。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巾陕,一起剝皮案震驚了整個濱河市讨跟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鄙煤,老刑警劉巖晾匠,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異梯刚,居然都是意外死亡凉馆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門亡资,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澜共,“玉大人,你說我怎么就攤上這事锥腻∴露” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵瘦黑,是天一觀的道長京革。 經(jīng)常有香客問我,道長供璧,這世上最難降的妖魔是什么存崖? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮睡毒,結(jié)果婚禮上来惧,老公的妹妹穿的比我還像新娘。我一直安慰自己演顾,他們只是感情好供搀,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著钠至,像睡著了一般葛虐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棉钧,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天屿脐,我揣著相機與錄音,去河邊找鬼宪卿。 笑死的诵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的佑钾。 我是一名探鬼主播西疤,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼休溶!你這毒婦竟也來了代赁?” 一聲冷哼從身側(cè)響起扰她,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芭碍,沒想到半個月后徒役,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡豁跑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年廉涕,在試婚紗的時候發(fā)現(xiàn)自己被綠了泻云。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艇拍。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宠纯,靈堂內(nèi)的尸體忽然破棺而出卸夕,到底是詐尸還是另有隱情,我是刑警寧澤婆瓜,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布快集,位于F島的核電站,受9級特大地震影響廉白,放射性物質(zhì)發(fā)生泄漏个初。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一猴蹂、第九天 我趴在偏房一處隱蔽的房頂上張望院溺。 院中可真熱鬧,春花似錦磅轻、人聲如沸珍逸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谆膳。三九已至,卻和暖如春撮躁,著一層夾襖步出監(jiān)牢的瞬間漱病,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工把曼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杨帽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓祝迂,卻偏偏與公主長得像睦尽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子型雳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355