C# sftp通过秘钥上传下载

 

一、适用场景

  我们平时习惯了使用ftp来上传下载文件,尤其是很多Linux环境下,我们一般都会通过第三方的SSH工具连接到Linux,但是当我们需要传输文件到Linux服务器当中,很多人习惯用ftp来传输,其实Linux默认是不提供ftp的,需要你额外安装FTP服务器。而且ftp服务器端会占用一定的VPS服务器资源。其实笔者更建议使用sftp代替ftp。

  主要因为:

一、可以不用额外安装任何服务器端程序。

二、会更省系统资源。

三、SFTP使用加密传输认证信息和传输数据,相对来说会更安全。

四、也不需要单独配置,对新手来说比较简单(开启SSH默认就开启了SFTP)。

二、主要区别

  FTP是一种文件传输协议,一般是为了方便数据共享的。包括一个FTP服务器和多个FTP客户端。FTP客户端通过FTP协议在服务器上下载资源。
而SFTP协议是在FTP的基础上对数据进行加密,使得传输的数据相对来说更安全。但是这种安全是以牺牲效率为代价的,也就是说SFTP的传输效率比FTP要低(不过现实使用当中,没有发现多大差别)。个人肤浅的认为就是:一;FTP要安装,SFTP不要安装。二;SFTP更安全,但更安全带来副作用就是的效率比FTP要低些。
 
三 本次讲解,私钥公钥问题 
       本次重点讲解sftp,跟据公司要求,这次做了一个sftp,sftp很多都是通过< ip,用户名,密码>  但是这次遇到一个问题,那么就是使用公钥,跟私钥的方式:进行访问服务器,  不太会写文字,描述,直接上程序 
秘钥支持:BEGI 之后跳过两个字节 后跟DSA或者RSA或者SSH 如果有这几个的才支持,别的应该不持之,可以试一下
 原本想把项目贴进来呢,回想了一下,发现我不会,如果想要sftp整个项目的可以加我QQ,ftp也有 1649514562
首先引用三个dll
   

 
string result;
            SFTPClass sftp = ToolsService.ConnSFTP("/download/", out result);//最小路径,也属于服务器已经存在的主目录
            //链接上传
            sftp.Connect();
           //判断服务器文件夹是否存在            
if (sftp.DirExist("/telSale/") == false) {
//创建文件夹 sftp.CreateDirectory(
"/telSale/"); } if (sftp.DirExist("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/") == false) { //一级一级的创建 sftp.CreateDirectory("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/"); } if (sftp.DirExist("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/") == false) { sftp.CreateDirectory("/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/"); } //上传 sftp.Put("D:\sftp_put\insPolicy.txt");//全文件名 文件支持各种格式 sftp.Disconnect(); //-----------------------下载----------------------------------------- //链接 SFTPClass sftpx = ToolsService.ConnSFTP("/upload/telSale /" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/", out result);//最小路径,也属于服务器已经存在的主目录 sftpx.Connect(); sftpx.Get("insPolicy.txt", "D:\sftp_put\upload");//第一个服务器文件名,第二个下载到哪里 sftpx.Disconnect();
 /// <summary>
        /// 连接SFTP,自动获取app.xml中的指定配置,创建好一个sftp
        /// sftp在使用操作前需要调用Connect方法,在不需要的时候要使用DisConnect,中间过程不需要断开连接
        /// </summary>
        /// <param name="ftpname">app.xml中配置的ftp名称</param>
        /// <param name="remotePath">FTP上的路径,不包含文件名,初始化的时候设置,一次连接长期使用.</param>
        /// <returns>创建成功,则返回SFTP实例</returns>
        public static SFTPClass ConnSFTP(string remotePath, out string errorMsg)
        {
            errorMsg = "";
            try
            {
                //采用ip跟用户名,公钥私钥的方式访问sftp,密码传递空,如果使用密码方式,要传递密码,私钥公钥方式可去除
                string url = "211.101.11.33";
               string username = "trade_name";
                string password = null;
                SFTPClass sftp = new SFTPClass(url, username, password, remotePath);

                return sftp;
            }
            catch (Exception e)
            {
                errorMsg = e.Message;
             
                return null;
            }
        }
using System;
using System.Text;
using Tamir.SharpSsh.jsch;

namespace Tms.Utils
{
    public class SFTPClass
    {
        private Session m_session;
        private Channel m_channel;
        private ChannelSftp m_sftp;
        private string remotePath = "/";//FTP上的路径,不包含文件名,路径应为"/"


        //private Tamir.SharpSsh.jsch.examples.Sftp.MyProgressMonitor m_monitor;
        private static readonly string defRemotePath = "/download/";//默认操作是都是从根目录开始。

        /// <summary>
        /// 实例化SFTP, 用于创建连接对象
        /// </summary>
        /// <param name="host">sftp IP地址</param>
        /// <param name="user">用户名</param>
        /// <param name="pwd">密码</param>
        /// <param name="ftpPath">FTP上的路径</param>
        public SFTPClass(string host, string user, string pwd, string ftpPath)
        {
            string[] arr = host.Split(':');
            string ip = arr[0];
            int port = 20000;//端口号替换
            if (arr.Length > 1) port = Int32.Parse(arr[1]);

            JSch jsch = new JSch();
            jsch.addIdentity("D:\MTS-SFTP\Privite-Key\Identity");//将私钥配置在客户端,这个配置的是私钥,公钥配置在了服务端
        
            m_session = jsch.getSession(user, ip, port);
            MyUserInfo ui = new MyUserInfo();
            ui.setPassword(pwd);
            m_session.setUserInfo(ui);
            if (!string.IsNullOrEmpty(ftpPath))
                this.remotePath = ftpPath;
        }

        /// <summary>
        /// SFTP连接状态
        /// </summary>
        public bool Connected { get { return m_session.isConnected(); } }

        /// <summary>
        /// 连接SFTP 
        /// </summary>
        /// <returns></returns>
        public bool Connect()
        {
            if (!Connected)
            {
                m_session.connect();
                m_channel = m_session.openChannel("sftp");
                m_channel.connect();
                m_sftp = (ChannelSftp)m_channel;
            }
            return true;
        }

        /// <summary>
        /// 断开SFTP 
        /// </summary>
        public void Disconnect()
        {
            if (Connected)
            {
                m_channel.disconnect();
                m_session.disconnect();
            }
        }

        /// <summary>
        /// 向SFTP存放文件  
        /// </summary>
        /// <param name="localPath">要上传FTP的文件全路径,包含文件名</param>
        /// <returns></returns>
        public bool Put(string localPath)
        {
            string path = "/download/telSale/" + DateTime.Now.ToString("yyyyMMdd") + "/insPolicy/";
            Tamir.SharpSsh.java.String src = new Tamir.SharpSsh.java.String(localPath);
            Tamir.SharpSsh.java.String dst = new Tamir.SharpSsh.java.String(path);
            m_sftp.put(src, dst);

            return true;
        }

        /// <summary>
        /// SFTP获取文件
        /// </summary>
        /// <param name="filename">FTP上的文件名,不需要包含路径</param>
        /// <param name="localPath">保存放文件的本地路径</param>
        /// <returns></returns>
        public bool Get(string filename, string localPath)
        {
            Tamir.SharpSsh.java.String src = new Tamir.SharpSsh.java.String(this.remotePath + filename);
            Tamir.SharpSsh.java.String dst = new Tamir.SharpSsh.java.String(localPath);
            //m_sftp.get(src, dst, m_monitor, ChannelSftp.OVERWRITE);
            m_sftp.get(src, dst);

            return true;
        }

        /// <summary>
        /// 删除SFTP上的文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool Delete(string fileName)
        {
            m_sftp.rm(this.remotePath + fileName);

            return true;
        }

        /// <summary>
        /// 目录是否存在
        /// </summary>
        /// <param name="dirName">目录名称必须从根开始</param>
        /// <returns></returns>
        public bool Exist(string dirName)
        {
            m_sftp.ls(dirName);

            return true;
        }
        /// <summary>
        /// 判断目录是否存在 建议使用这个
        /// </summary>
        /// <param name="dirName"></param>
        /// <returns></returns>
        public bool DirExist(string dirName)
        {
            try
            {
                m_sftp.ls(defRemotePath + dirName.Trim());
                return true;
            }
            catch (Tamir.SharpSsh.jsch.SftpException)
            {
                return false;//执行ls命令时出错,则目录不存在。
            }
        }

        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="dirName">目录名称必须从根开始</param>
        /// <returns></returns>
        public void CreateDirectory(string dirName)
        {
            bool isExist = false;
            Tamir.SharpSsh.java.util.Vector vvv = m_sftp.ls(defRemotePath);
            foreach (Tamir.SharpSsh.jsch.ChannelSftp.LsEntry fileName in vvv)
            {
                string name = fileName.getFilename();
                if (name == dirName.Trim('/'))
                {
                    isExist = true;
                }
            }
            if (!isExist)
            {
                m_sftp.mkdir(defRemotePath + dirName.Trim());
            }
        }

        /// <summary>
        /// 获取SFTP文件名称列表   
        /// </summary>
        /// <param name="remotePath">SFTP路径</param>
        /// <returns></returns>
        public string[] GetFileList()
        {
            try
            {
                Tamir.SharpSsh.java.util.Vector vector = m_sftp.ls(this.remotePath);
                StringBuilder fileNames = new StringBuilder();
                foreach (Tamir.SharpSsh.jsch.ChannelSftp.LsEntry q in vector)
                {
                    string fileName = q.getFilename();
                    fileNames.Append(fileName);
                    fileNames.Append("
");
                }
                fileNames.Remove(fileNames.ToString().LastIndexOf('
'), 1);

                return fileNames.ToString().Split('
'); ;
            }
            catch
            {
                this.Disconnect();
                return null;
            }
        }

        //登录验证信息        
        public class MyUserInfo : UserInfo
        {
            String passwd;
            public String getPassword() { return passwd; }
            public void setPassword(String passwd) { this.passwd = passwd; }

            public String getPassphrase() { return null; }
            public bool promptPassphrase(String message) { return true; }

            public bool promptPassword(String message) { return true; }
            public bool promptYesNo(String message) { return true; }
            public void showMessage(String message) { }
        }
    }
}
 
   
原文地址:https://www.cnblogs.com/zwq521/p/9303395.html