我使用 FileZilla 作为服务器和 DNS 服务,这样我就不必使用我的本地计算机 IP(但我在这两种方法上都尝试了以下方法)。
在尝试 System.Net.FtpWebRequest 工作后,我已经阅读(包括一些关于 SO 的帖子)并发现 SSL 支持对于该库来说不是很充分。它正在使用常规 FTP,但是当我尝试强制使用 SSL 时,我收到了证书验证错误消息:The remote certificate is invalid according to the validation procedure.
所以,我做了一些搜索,发现了Alex FTPS 客户端库。这是我写的代码:
class FTPSWorker
{
public static void UploadFile(string sourceFile, string targetFile, string ftpIP, string ftpUser, string ftpPass)
{
try
{
using (FTPSClient client = new FTPSClient())
{
client.Connect(ftpIP, new NetworkCredential(ftpUser, ftpPass),
ESSLSupportMode.CredentialsRequired | ESSLSupportMode.DataChannelRequested);
client.SetTransferMode(ETransferMode.Binary);
client.PutFile(sourceFile, targetFile);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
不幸的是,我得到了同样的证书错误。但是,我可以使用 FileZilla 客户端完美地访问 FTP 服务器。所以,我认为必须有一个证书问题。
我应该注意到我的服务器显示了以下日志条目:
Welcome Message
AUTH TLS
234 Using authentication type TLS
SSL connection established
disconnected
当客户端(C# WPF 应用程序)收到此错误时:
The remote certificate is invalid according to the validation procedure.
如果我使用 .NET 库和 MSDN 代码,这绝对是完全相同的错误。
我做了更多的研究并找到了类似于这些的解决方案:
“根据验证程序,远程证书无效。” 使用 Gmail SMTP 服务器
但是它们看起来像是有风险的黑客......虽然它们确实有效,但除了当前使用的基本是/否之外,是否有办法让认证信息出现并且可能让用户验证/安装它?
我现在的代码(我放弃了 Alex 的库并回到默认的 .NET):
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(FTPWorker.ValidateServerCertificate);
public class FTPWorker
{
public static void UploadFile(string sourceFile, string targetFile, string ftpIP, string ftpUser, string ftpPass)
{
try
{
string filename = "ftp://" + ftpIP + "/test/" + targetFile;
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename);
ftpReq.Method = WebRequestMethods.Ftp.UploadFile;
ftpReq.Credentials = new NetworkCredential(ftpUser, ftpPass);
ftpReq.UsePassive = true;
ftpReq.EnableSsl = true;
ftpReq.UseBinary = true;
ftpReq.KeepAlive = false;
byte[] b = File.ReadAllBytes(sourceFile);
ftpReq.ContentLength = b.Length;
using (Stream s = ftpReq.GetRequestStream())
{
s.Write(b, 0, b.Length);
}
FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse();
if (ftpResp != null)
{
MessageBox.Show(ftpResp.StatusDescription);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
else
{
if (System.Windows.Forms.MessageBox.Show("The server certificate is not valid.\nAccept?",
"Certificate Validation", System.Windows.Forms.MessageBoxButtons.YesNo,
System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
return true;
else
return false;
}
}
}