C#訪問基於公開鍵認證的SFTP伺服器

來源:互聯網
上載者:User

什麼是SFTP,公開鍵認證,

   SFTP可不是FTP協議的擴充,他是基於SSH的檔案傳輸通訊協定。 而當SFTP伺服器登入有用戶端的公開鍵時,用戶端就可以用自己的私人鍵去跟伺服器握手(handshake)已實現登入而不需要輸入密碼。而這種方式被稱為公開鍵認證。

1 建SFTP伺服器 

首先當然是先建一個local SFTP server ,我使用的是SilverSHielD. 它是非商用的話,免費,當然只能同時又三個串連,下載,安裝。

 

2 設定管理員

開啟"SilverSHielD Management Console",然後connect

 

Log Path設一下,然後切換到user,追加

 username等等,填好.

關鍵的在manage User’s Public Keys, 開啟, Add

 正規的流程應該是客戶用winscp等工具產生自己的Key-pair,然後把public 可以貼到 actual Public Key, 俺們自己測試用,所以直接Generate,

然後會提示你儲存私人鍵,這是一定要選 OpenSSH Private Key Files ,這個產生的檔案就是用戶端認證用私人鍵。

依次confirm下去,配置完成。

 

3 下載訪問SFTP的library

我用的是 SSH.NET Library

 

4,存取碼

 A,說不定另一個客戶用的是FTP,做一個通用的介面先:

public interface IFtpClient     {         /// <summary>         /// 串連伺服器         /// </summary>         /// <returns>true:成功;false:失敗</returns>         bool Connect();         /// <summary>         /// 中斷連線         /// </summary>         void DisConnect();          /// <summary>         /// 取得檔案清單         /// </summary>         /// <param name="path">路徑</param>         /// <returns></returns>         List<string> ListFiles(string path);          /// <summary>         /// 下載檔案          /// </summary>         /// <param name="remoteFileName">包含全路徑的伺服器端檔案名稱</param>         /// <param name="localFileName">本地儲存的檔案名稱</param>         /// <returns></returns>         bool Download(string remoteFileName, string localFileName);          /// <summary>         /// 上傳檔案         /// </summary>         /// <param name="localFileName">待上傳的檔案</param>         /// <param name="remoteFileName">伺服器端檔案名稱</param>         /// <returns></returns>         bool Upload(string localFileName, string remoteFileName);          /// <summary>         /// 檔案改名         /// </summary>         /// <param name="localFileName">包含全路徑的源檔案名稱</param>         /// <param name="remoteFileName">包含全路徑的新檔案名稱</param>         /// <returns></returns>         bool Rename(string orgFileName, string newFileName);          /// <summary>         /// 刪除檔案         /// </summary>         /// <param name="orgFileName"></param>         /// <param name="newFileName"></param>         /// <returns></returns>         bool Delete(string fileName);     }

 

B 定義實現:

public class SFtpClient : IFtpClient     {         SftpClient sftp = null;          /// <summary>         /// 建構函式         /// </summary>         /// <param name="host">sftp伺服器名或IP</param>         /// <param name="port">連接埠,預設22</param>         /// <param name="user"></param>         /// <param name="privateKey"></param>         /// <param name="passPhrase"></param>         public SFtpClient(string host, int? port, string user, string privateKey, string passPhrase)         {             PrivateKeyFile keyFile = null;              if (string.IsNullOrEmpty(passPhrase))             {                 keyFile = new PrivateKeyFile(privateKey);             }             else             {                 keyFile = new PrivateKeyFile(privateKey, passPhrase);             }              if (port.HasValue)             {                 sftp = new SftpClient(host, port.Value, user, keyFile);             }             else             {                 sftp = new SftpClient(host, user, keyFile);             }               if (sftp != null)             {                 sftp.ConnectionInfo.RetryAttempts = 5;                 sftp.ConnectionInfo.Timeout = new TimeSpan(0, 3, 0);             }         }          public bool Connect()         {             if (sftp == null)             {                 return false;             }              if (sftp.IsConnected)             {                 return true;             }              try             {                 sftp.Connect();                 return true;             }             catch (Exception ex)             {                 string server = string.Format("{0}:{1}", sftp.ConnectionInfo.Username, sftp.ConnectionInfo.Host);                 // 我用的是nLog來記錄錯誤記錄檔。                 // logger.Error("[{0}] SFTP串連發生錯誤。", server, ex);                 return false;             }         }          public void DisConnect()         {             if (sftp == null)             {                 return;             }             if (!sftp.IsConnected)             {                 return;             }              try             {                 sftp.Disconnect();                 sftp.Dispose();                 sftp = null;             }             catch (Exception ex)             {                 //logger.Error("SFTP中斷連線發生錯誤。", ex);             }         }          /// <summary>         /// 取得檔案清單         /// </summary>         /// <param name="path">路徑</param>         /// <returns></returns>         public List<string> ListFiles(string path)         {              if (!Connect())             {                 return null;             }              List<string> files = new List<string>();             try             {                 sftp.ChangeDirectory("/");                 sftp.ListDirectory(path).ToList().ForEach(f =>                     {                          files.Add(f.FullName);                     });                  return files;             }             catch (Exception ex)             {                 // logger.Error("[{0}] 取得檔案清單發生錯誤。", Path, ex);                 return null;             }         }          /// <summary>         /// 下載檔案          /// </summary>         /// <param name="remoteFileName">包含全路徑的伺服器端檔案名稱</param>         /// <param name="localFileName">本地儲存的檔案名稱</param>         /// <returns></returns>         public bool Download(string remoteFileName, string localFileName)         {             if (!Connect())             {                 return false;             }              try             {                 sftp.ChangeDirectory("/");                 FileStream fs = File.OpenWrite(localFileName);                 sftp.DownloadFile(remoteFileName, fs);                 fs.Close();                 return true;             }             catch (Exception ex)             {                 //logger.Error("[{0}] 檔案下載發生錯誤。", remoteFileName, ex);                 return false;             }         }          /// <summary>         /// 上傳檔案         /// </summary>         /// <param name="localFileName">待上傳的檔案</param>         /// <param name="remoteFileName">伺服器端檔案名稱</param>         /// <returns></returns>         public bool Upload(string localFileName, string remoteFileName)         {             if (!Connect())             {                 return false;             }              try             {                 sftp.ChangeDirectory("/");                  FileStream fs = File.OpenRead(localFileName);                 sftp.UploadFile(fs, remoteFileName, true);                 fs.Close();                 Thread.Sleep(1000);                 return true;             }             catch (Exception ex)             {                 //logger.Error("[{0}] 檔案上傳發生錯誤。", localFileName, ex);                 return false;             }         }          /// <summary>         /// 檔案改名         /// </summary>         /// <param name="localFileName">包含全路徑的源檔案名稱</param>         /// <param name="remoteFileName">包含全路徑的新檔案名稱</param>         /// <returns></returns>         public bool Rename(string orgFileName, string newFileName)         {             if (!Connect())             {                 return false;             }              try             {                 sftp.ChangeDirectory("/");                  sftp.RenameFile(orgFileName, newFileName);                 return true;             }             catch (Exception ex)             {                 //logger.Error("[{0}] 檔案改名發生錯誤。", localFileName, ex);                 return false;             }         }           /// <summary>         /// 刪除檔案         /// </summary>         /// <param name="orgFileName"></param>         /// <param name="newFileName"></param>         /// <returns></returns>         public bool Delete(string fileName)         {             if (!Connect())             {                 return false;             }              try             {                 sftp.ChangeDirectory("/");                  sftp.DeleteFile(fileName);                 return true;             }             catch (Exception ex)             {                 //logger.Error("[{0}] 檔案刪除發生錯誤。", localFileName, ex);                 return false;             }         }     }

案例下載

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.