Transfer files over FTPS (SSL/TLS) using C#.Net
Asked Answered
P

2

19

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 secure FTPS connection.

They provided me with a *.cr_ certificate file. If I open the file in notepad I see something like this (but with real keys not foobar obviously).

-----BEGIN RSA PRIVATE   
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
FOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBARFOOBAR    
-----END CERTIFICATE-----

How can I use this certificate file to connect to the FTPS server to upload and download files? Forgive me but I'm very new to anything involving transferring files over a network, secure connections, certificates, public keys, private keys, etc...etc...

I think I'd want to use an FtpWebRequest object and set the EnableSsl property to true. But I'm not not sure where this certificate file comes into play.

Pyroligneous answered 8/10, 2009 at 0:7 Comment(0)
S
27

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;
    }
Scaphoid answered 4/12, 2012 at 17:56 Comment(5)
Can you explain this part "X509Certificate cert = X509Certificate.CreateFromCertFile(@"C:\MyCertDir\MyCertFile.cer");" do i need the certificate locally to access the FTPS?Dittmer
@Dittmer The OPs question was how to authenticate his client application to the FTPS server using a certificate that was issued to him and stored in a file. For FTPS where the user is authenticated via just a username and password this is not necessary. For your purposes see #9100238.Scaphoid
I know this is a bit old.. but if I understand correctly, this could be a bit misleading - The first part talks about client certificates, while the second part talks about ServerCertificateValidationCallback which is the client validating the server certificate, not the one used on the first part..Kordofan
@JonyAdamit After rereading this I can see where it might be a little confusing. I made some updates to improve clarity.Scaphoid
Thanks @Scaphoid :-)Kordofan
C
2

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.

Corabelle answered 8/10, 2009 at 0:23 Comment(2)
I'm looking at that article and a copy of the source code. But I can't figure out where I would add in this certificate file.Pyroligneous
Thanks Eric J, I actaully have the same question as the original poster and that's the code that I'm using (what you have linked)....still trying to figure out how to pass my "hostkey" into that code.Lehman

© 2022 - 2024 — McMap. All rights reserved.