I\'m writing an application that syncs files over an FTP site. Right now it\'s working by connecting through regular FTP, but now our IT guys want to set this up over a secu
If you're using the FtpWebRequest Class, you just need to add some things to the setup of the request to utilize a client certificate file. Be sure to include the using System.Security.Cryptography.X509Certificates;
statement.
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;
Also, if you have problems with the server certificate generating exceptions in the client you may need to implement your own certificate validation callback method for use with the ServicePointManager.ServerCertificateValidationCallback Property. This can be as simple as always returning true or be more sophisticated like the one I use for debugging:
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;
}
This article explains how to do it, with source code.
The purpose of this article is to create a C # FTP client in Secure mode, so if you don’t have much knowledge of FTPS, I advise you to take a look at this: FTPS.
In the .NET Framework, to upload a file in FTPS mode, we generally use the FtpWebRequest class, but you can not send commands with quote arguments, and even if you search on the web, you will not find a concrete example of a secured C# FTP client.
It’s for those reasons I decided to create this article.