Передача файлов через FTPS (SSL/TLS) с использованием С#.Net

Я пишу приложение, которое синхронизирует файлы через FTP-сайт. Сейчас он работает, подключаясь через обычный FTP, но теперь наши ИТ-ребята хотят установить это через безопасное соединение FTPS.

Они предоставили мне файл сертификата *.cr_. Если я открою файл в блокноте, я увижу что-то вроде этого (но с реальными ключами явно не foobar).

-----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-----

Как я могу использовать этот файл сертификата для подключения к серверу FTPS для загрузки и загрузки файлов? Простите меня, но я очень новичок в деле передачи файлов по сети, защищенных подключений, сертификатов, открытых ключей, закрытых ключей и т.д. И т.д....

Я думаю, что хочу использовать объект FtpWebRequest и установить для свойства EnableSsl значение true. Но я не уверен, где этот файл сертификата вступает в игру.

Ответ 1

Если вы используете класс FtpWebRequest, вам просто нужно добавить некоторые вещи к настройке запроса. Обязательно включите оператор using System.Security.Cryptography.X509Certificates;.

    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;

Кроме того, если у вас возникли проблемы с получением сертификатов, вам может понадобиться реализовать свой собственный метод проверки валидации сертификата для использования с ServicePointManager.ServerCertificateValidationCallback Property. Это может быть так же просто, как всегда возвращать 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;
    }

Ответ 2

В этой статье объясняется, как это сделать, с исходным кодом.

Цель этой статьи - создать FTP-клиент С# в безопасном режиме, поэтому, если у вас нет много знаний о FTPS, я советую вам взглянуть на это: FTPS.

В .NET Framework для загрузки файла в режиме FTPS мы обычно используем класс FtpWebRequest, но вы не можете отправлять команды с аргументами котировки, и даже если вы выполняете поиск в Интернете, вы не найдете конкретного примера защищенного FTP-клиента С#.

В связи с этим я решил создать эту статью.