版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33538554/article/details/52807195
安全文件传送:SFTP (介绍,下载,配置,C#源码)
SFTP 简介:
SFTP是Secure File Transfer Protocol的缩写,是安全文件传送协议。可以为传输文件提供一种安全的加密方法。跟FTP几乎语法功能一样。
SFTP是SSH的一部分,是一种传输档案至Blogger伺服器的安全方式。它本身没有单独的守护进程,必须使用sshd守护进程来完成相应的连接操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以使用SFTP是十分安全的。但由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多。在对网络安全性要求更高时,代替FTP使用。
SFTP客户端下载:
WinSCP 等等
SFTP秘钥配置:
当WinSCP安装成功,在目录中找到puttygen.exe进行秘钥配置(public ,private.ppk)
SFTP 操作类:
- public class SftpHelper
{
SftpClient sftp = null;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sftpIP">sftp服务器IP</param>
/// <param name="sftpPort">端口,默认22</param>
/// <param name="sftpName">用户名</param>
/// <param name="privateKey">用户私钥</param>
/// <param name="sftpPwd">密码</param>
public SftpHelper(string sftpIP, string sftpName, string sftpPwd, string privateKey, int? sftpPort)
{
PrivateKeyFile keyFile = null;
if (string.IsNullOrEmpty(sftpPwd))
{
//使用秘钥验证
keyFile = new PrivateKeyFile(privateKey);
}
else
{
//使用带口令的秘钥验证
keyFile = new PrivateKeyFile(privateKey, sftpPwd);
}
if (sftpPort.HasValue)
{
//设置端口
sftp = new SftpClient(sftpIP, sftpPort.Value, sftpName, keyFile);
}
else
{
//默认端口
sftp = new SftpClient(sftpIP, sftpName, keyFile);
}
if (sftp != null)
{
sftp.ConnectionInfo.RetryAttempts = 5;
sftp.ConnectionInfo.Timeout = new TimeSpan(0, 3, 0);
}
}
/// <summary>
/// SFTP连接
/// </summary>
/// <returns></returns>
public bool Connect()
{
if (sftp == null)
{
return false;
}
if (sftp.IsConnected)
{
return true;
}
try
{
sftp.Connect();
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 关闭
/// </summary>
public void DisConnect()
{
if (sftp == null)
{
return;
}
if (!sftp.IsConnected)
{
return;
}
try
{
sftp.Disconnect();
sftp.Dispose();
sftp = null;
}
catch (Exception)
{
return;
}
}
/// <summary>
/// 取得文件列表
/// </summary>
/// <param name="path">路径获取所有文件</param>
/// <param name="catalogue">路径获取某个文件</param>
/// <returns></returns>
public List<string> GetFileList(string path, string catalogue)
{
if (!Connect())
{
return null;
}
List<string> files = new List<string>();
try
{
//sftp.ChangeDirectory(catalogue);
sftp.ListDirectory(path).ToList().ForEach(f =>
{
files.Add(f.FullName);
});
return files;
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// 下载文件
/// </summary>
/// <param name="remoteFileName">包含全路径的服务器端文件名</param>
/// <param name="localFileName">本地保存的文件名</param>
/// <param name="catalogue">下载文件存放的路径</param>
/// <returns></returns>
public bool Get(string remoteFileName, string localFileName, string catalogue)
{
if (!Connect())
{
return false;
}
try
{
sftp.ChangeDirectory(catalogue);
FileStream fs = File.OpenWrite(localFileName);
sftp.DownloadFile(remoteFileName, fs);
fs.Close();
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="localFileName">待上传的文件路径</param>
/// <param name="stream">待上传的文件流</param>
/// <param name="remoteFileName">服务器端文件名</param>
/// <param name="catalogue">上传文件存放的路径</param>
/// <returns></returns>
public bool Put(Stream stream, string remoteFileName, string catalogue)
{
if (!Connect())
{
return false;
}
try
{
sftp.ChangeDirectory(catalogue);
//FileStream fs = File.OpenRead(localFileName);//通过本地路径进行读取流
sftp.UploadFile(stream, remoteFileName, true);//true 同名文件将被覆盖
stream.Close();
Thread.Sleep(1000);
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="SFtpPath">文件夹名</param>
/// <param name="catalogue">文件夹路径</param>
/// <returns></returns>
public bool DirectoryExist(string SFtpPath,string catalogue)
{
var list = sftp.ListDirectory(catalogue);
if (list.Where(x => x.IsDirectory && x.Name == SFtpPath).Count() != 0)
{
return true;
}
try
{
sftp.CreateDirectory(SFtpPath);
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 文件改名
/// </summary>
/// <param name="localFileName">包含全路径的源文件名</param>
/// <param name="remoteFileName">包含全路径的新文件名</param>
/// <param name="catalogue">文件路径</param>
/// <returns></returns>
public bool Rename(string orgFileName, string newFileName, string catalogue)
{
if (!Connect())
{
return false;
}
try
{
//sftp.ChangeDirectory(catalogue);
sftp.RenameFile(orgFileName, newFileName);
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="fileName">文件名</param>
/// <param name="catalogue">文件路径</param>
/// <returns></returns>
public bool Delete(string fileName, string catalogue)
{
if (!Connect())
{
return false;
}
try
{
sftp.ChangeDirectory(catalogue);
sftp.DeleteFile(fileName);
return true;
}
catch (Exception)
{
return false;
}
}
}
注意:
1.需要引用using Renci.SshNet; using System.IO; using System.Threading;
2.操作SFTP的方法很多,我这里是Renci.SshNet,可能方法的不同,秘钥的格式就可能不同,所以在生成秘钥之后,使用puttygen.exe转换为Export OpenSSH Key
3.将私钥放置项目的Debug目录下