使用C#.Net通过FTPS(SSL/TLS)传输文件

使用C#.Net通过FTPS(SSL/TLS)传输文件,c#,ssl,ftpwebrequest,ftps,C#,Ssl,Ftpwebrequest,Ftps,我正在编写一个通过FTP站点同步文件的应用程序。现在它通过常规的FTP连接工作,但现在我们的it人员希望通过安全的FTPS连接来设置 他们向我提供了一个*.cr_u.证书文件。如果我在记事本中打开文件,我会看到类似的内容(但使用的是真正的键,而不是foobar) 如何使用此证书文件连接到FTPS服务器以上载和下载文件?请原谅,我对任何涉及通过网络传输文件、安全连接、证书、公钥、私钥等的事情都很陌生 我想我应该使用FtpWebRequest对象并将EnableSsl属性设置为true。但是我不确定

我正在编写一个通过FTP站点同步文件的应用程序。现在它通过常规的FTP连接工作,但现在我们的it人员希望通过安全的FTPS连接来设置

他们向我提供了一个*.cr_u.证书文件。如果我在记事本中打开文件,我会看到类似的内容(但使用的是真正的键,而不是foobar)

如何使用此证书文件连接到FTPS服务器以上载和下载文件?请原谅,我对任何涉及通过网络传输文件、安全连接、证书、公钥、私钥等的事情都很陌生

我想我应该使用FtpWebRequest对象并将EnableSsl属性设置为true。但是我不确定这个证书文件在哪里起作用。

用源代码解释了如何做到这一点

本文的目的是在安全模式下创建一个C#FTP客户端,因此如果您对FTPS不太了解,我建议您看看这个:FTPS

在.NET Framework中,要以FTPS模式上载文件,我们通常使用FtpWebRequest类,但您不能发送带有引号参数的命令,即使您在web上搜索,也找不到安全C#FTP客户端的具体示例

正是出于这些原因,我决定写这篇文章

如果您正在使用,则只需在请求的设置中添加一些内容,以利用客户端证书文件。确保使用System.Security.Cryptography.X509证书包含
语句

    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUrl);
    request.Credentials = new NetworkCredential(userName, password);

    request.EnableSsl = true;
    //ServicePointManager.ServerCertificateValidationCallback = ServicePointManager_ServerCertificateValidationCallback;

    X509Certificate cert = X509Certificate.CreateFromCertFile(@"C:\MyCertDir\MyCertFile.cer");
    X509CertificateCollection certCollection = new X509CertificateCollection();
    certCollection.Add(cert);

    request.ClientCertificates = certCollection;
此外,如果在客户端中服务器证书生成异常时遇到问题,则可能需要实现自己的证书验证回调方法以用于。这可以像总是返回true一样简单,也可以像我用于调试的那样更复杂:

    public static bool ServicePointManager_ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        bool allowCertificate = true;

        if (sslPolicyErrors != SslPolicyErrors.None)
        {
            Console.WriteLine("Accepting the certificate with errors:");
            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
            {
                Console.WriteLine("\tThe certificate subject {0} does not match.", certificate.Subject);
            }

            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
            {
                Console.WriteLine("\tThe certificate chain has the following errors:");
                foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                {
                    Console.WriteLine("\t\t{0}", chainStatus.StatusInformation);

                    if (chainStatus.Status == X509ChainStatusFlags.Revoked)
                    {
                        allowCertificate = false;
                    }
                }
            }

            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
            {
                Console.WriteLine("No certificate available.");
                allowCertificate = false;
            }

            Console.WriteLine();
        }

        return allowCertificate;
    }

我正在看那篇文章和一份源代码。但是我不知道我应该在这个证书文件中添加到哪里。谢谢Eric J,我实际上有和原始海报相同的问题,这就是我正在使用的代码(你链接的内容)…仍然在试图找出如何将我的“hostkey”传递到该代码中。你能解释一下这部分吗“X509Certificate cert=X509Certificate.CreateFromCertFile(@“C:\MyCertDir\MyCertFile.cer”);“我需要本地证书才能访问FTPS吗?@Reynan OPs的问题是如何使用发给他的证书并存储在文件中对FTPS服务器的客户端应用程序进行身份验证。对于仅通过用户名和密码对用户进行身份验证的FTPS,这是不必要的。出于您的目的,请参阅。我知道这是一个b它很旧..但如果我理解正确,这可能有点误导-第一部分讨论客户机证书,而第二部分讨论
ServerCertificateValidationCallback
,这是验证服务器证书的客户机,而不是第一部分中使用的客户机..@JonyAdamit在重读这篇文章后,我可以看到它的位置可能有点混乱。我做了一些更新以提高清晰度。谢谢@JamieSee:-)
    public static bool ServicePointManager_ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        bool allowCertificate = true;

        if (sslPolicyErrors != SslPolicyErrors.None)
        {
            Console.WriteLine("Accepting the certificate with errors:");
            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
            {
                Console.WriteLine("\tThe certificate subject {0} does not match.", certificate.Subject);
            }

            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
            {
                Console.WriteLine("\tThe certificate chain has the following errors:");
                foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                {
                    Console.WriteLine("\t\t{0}", chainStatus.StatusInformation);

                    if (chainStatus.Status == X509ChainStatusFlags.Revoked)
                    {
                        allowCertificate = false;
                    }
                }
            }

            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
            {
                Console.WriteLine("No certificate available.");
                allowCertificate = false;
            }

            Console.WriteLine();
        }

        return allowCertificate;
    }