web-dev-qa-db-ja.com

C#.Netを使用してFTPS(SSL / TLS)経由でファイルを転送する

FTPサイトを介してファイルを同期するアプリケーションを書いています。現在、通常のFTPを介して接続することで機能していますが、今では、IT担当者が安全な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に設定したいと思います。しかし、この証明書ファイルがどこで機能するかはわかりません。

16
Eric Anastas

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 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;
    }
25
JamieSee

この記事 は、ソースコードを使用してその方法を説明しています。

この記事の目的は、セキュアモードでC#FTPクライアントを作成することです。そのため、FTPSについての知識があまりない場合は、FTPSを参照することをお勧めします。

.NET Frameworkでは、FTPSモードでファイルをアップロードするために、通常はFtpWebRequestクラスを使用しますが、引用引数を使用してコマンドを送信することはできません。Webで検索しても、セキュリティで保護された具体的な例は見つかりませんC#FTPクライアント。

このような理由から、この記事を作成することにしました。

1
Eric J.