Передача файлов через FTPS (SSL / TLS) с использованием C # .Net - PullRequest
15 голосов
/ 08 октября 2009

Я пишу приложение, которое синхронизирует файлы через 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. Но я не уверен, где этот файл сертификата вступает в игру.

Ответы [ 2 ]

25 голосов
/ 04 декабря 2012

Если вы используете FtpWebRequest Class , вам просто нужно добавить некоторые вещи в настройку запроса для использования файла сертификата клиента. Обязательно включите оператор 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 . Это может быть так же просто, как всегда возвращать 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 голосов
/ 08 октября 2009

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

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

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

Именно по этим причинам я решил создать эту статью.

...