GrapeCity Secure FTP for .NET 4.0J > FTPサーバーとの接続 > SSLでサーバーへ接続する |
本製品は、FTPS(File Transfer Protocol over SSL/TLS)でのSSL通信に対応しています。
SSLを使用してFTPサーバーとセキュアなデータのやり取りを行うには、サーバーとの接続時にFtpSecurityクラスの各種プロパティを設定し、さらに同クラスのValidationCallbackフィールドにサーバーのSSL証明書を検証するためのメソッドを指定します。その他の設定や処理は、通常の接続方法と同じです。
|
SSLでサーバーに接続する、もっとも単純な方法のサンプルコードを示します。
続きを読む
ValidationCallbackフィールドには、サーバーのSSL証明書を検証するためのメソッドを指定します。本来このメソッドには、証明書の妥当性をチェックし、問題がない場合はTrue、問題がある場合はFalseを戻り値として返す処理を実装します。
ただし、以下のサンプルコードではメソッド内で証明書の妥当性を判断していません。この場合、サーバーから受信した証明書が信頼されないものであっても、その証明書を承認してSSL通信が確立されます。
この方法は、接続先が信頼できるサーバーであることがあらかじめ分かっている場合や、テスト用サーバーに証明書作成ツール(Makecert.exe)で作成した自己証明書を置いた場合など、SSL証明書の検証を省略しても問題のない条件下のみで利用できます。
Visual Basic |
コードのコピー |
---|---|
Imports System.Net.Security Imports System.Security.Authentication Imports System.Security.Cryptography.X509Certificates Private Sub explicitLogin() ' 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 Ftp1.Session.RemoteEndPoint.HostNameOrAddress = "MyFtpServer" Ftp1.Session.Username = "myUsername" Ftp1.Session.Password = "myPassword" ' データの暗号化を有効にします。 Ftp1.Session.Security.EncryptData = True ' Explicit(明示的)モードを指定します。 Ftp1.Session.Security.EncryptControl = Dart.Ftp.EncryptControl.Explicit ' サーバーのSSL証明書を検証する際に呼び出されるコールバック・メソッドを指定します。 Ftp1.Session.Security.ValidationCallback = AddressOf remoteCertificateValidation ' FTPサーバーに接続します。 Ftp1.Connect() ' 設定したユーザー名とパスワードでログインします。 Ftp1.Authenticate() End Sub Private Function remoteCertificateValidation(ByVal sender As Object, ByVal remoteCertificate As X509Certificate, _ ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean ' SSL証明書の検証を行わず、すべての証明書に対してTrue(問題なし)を返します。 Return True End Function |
C# |
コードのコピー |
---|---|
using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; private void explicitLogin() { // 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 ftp1.Session.RemoteEndPoint.HostNameOrAddress = "myFtpServer"; ftp1.Session.Username = "myUsername"; ftp1.Session.Password = "myPassword"; // データの暗号化を有効にします。 ftp1.Session.Security.EncryptData = true; // Explicit(明示的)モードを指定します。 ftp1.Session.Security.EncryptControl = Dart.Ftp.EncryptControl.Explicit; // サーバーのSSL証明書を検証する際に呼び出されるコールバック・メソッドを指定します。 ftp1.Session.Security.ValidationCallback = remoteCertificateValidation; // FTPサーバーに接続します。 ftp1.Connect(); // 設定したユーザー名とパスワードでログインします。 ftp1.Authenticate(); } private bool remoteCertificateValidation(Object sender, X509Certificate remoteCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { // SSL証明書の検証を行わず、すべての証明書に対してTrue(問題なし)を返します。 return true; } |
前述の「SSL証明書を検証せずに接続する」方法では、サーバーのSSL証明書をすべて「問題なし」と見なしてSSL接続を行っていました。次はSSL証明書を検証した上で、SSLでサーバーに接続するサンプルコードを示します。
続きを読む
サーバーのSSL証明書を検証して、問題がない場合はTrue、問題がある場合はFalseを戻り値として返すメソッドを作成し、そのメソッドをValidationCallbackフィールドに指定します。この検証処理はConnectメソッドによる接続処理の際に実行されますが、Falseが返された場合はAuthenticateメソッドによるログイン処理で例外が発生しますので、Abortメソッドを実行して強制的に接続を閉じます。
ValidationCallbackフィールドに指定する、サーバーのSSL証明書を検証するメソッドは、RemoteCertificateValidationCallbackデリゲート型(System.Net.Security名前空間のクラス)のメソッドです。以下のサンプルコードのremoteCertificateValidationメソッドでは.NET Framework標準の機能のみを使用して、SSL証明書の検証を行っています。各処理の詳細については、MSDNライブラリなどを参照してください。
Visual Basic |
コードのコピー |
---|---|
Imports System.Net.Security Imports System.Security.Authentication Imports System.Security.Cryptography.X509Certificates Private Sub explicitLogin() ' 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 Ftp1.Session.RemoteEndPoint.HostNameOrAddress = "MyFtpServer" Ftp1.Session.Username = "myUsername" Ftp1.Session.Password = "myPassword" ' データの暗号化を有効にします。 Ftp1.Session.Security.EncryptData = True ' Explicit(明示的)モードを指定します。 Ftp1.Session.Security.EncryptControl = Dart.Ftp.EncryptControl.Explicit ' サーバーのSSL証明書を検証する際に呼び出されるコールバック・メソッドを指定します。 Ftp1.Session.Security.ValidationCallback = AddressOf remoteCertificateValidation ' FTPサーバーに接続します。 Ftp1.Connect() Try ' 設定したユーザー名とパスワードでログインします。 Ftp1.Authenticate() Catch ex As Exception ' 証明書の検証結果が不正(False)だった場合は、強制的に接続を閉じます。 Ftp1.Abort() End Try End Sub ' サーバーのSSL証明書を検証するメソッドの一例です。 Private Function remoteCertificateValidation(ByVal sender As Object, ByVal remoteCertificate As X509Certificate, _ ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean ' サーバー証明書に問題がない場合、trueを返します。 If sslPolicyErrors = SslPolicyErrors.None Then Return True End If Dim acceptCertificate As Boolean = True Dim msg As String = "このサーバーの証明書には、以下の問題があります。" & Constants.vbCrLf ' サーバーが証明書を提示しなかった場合 If (sslPolicyErrors And _ SslPolicyErrors.RemoteCertificateNotAvailable) = SslPolicyErrors.RemoteCertificateNotAvailable Then msg = msg & Constants.vbCrLf & " - サーバーから証明書が提示されませんでした。" & Constants.vbCrLf acceptCertificate = False Else ' 証明書の名前が一致しない場合 If ((sslPolicyErrors And _ SslPolicyErrors.RemoteCertificateNameMismatch) = SslPolicyErrors.RemoteCertificateNameMismatch) Then msg = msg & Constants.vbCrLf & _ " - 証明書の名前が一致しませんでした。" & Constants.vbCrLf acceptCertificate = False End If ' 証明書に関するその他の問題がある場合 If (sslPolicyErrors And _ SslPolicyErrors.RemoteCertificateChainErrors) = SslPolicyErrors.RemoteCertificateChainErrors Then For Each item As X509ChainStatus In chain.ChainStatus If item.Status <> X509ChainStatusFlags.RevocationStatusUnknown AndAlso _ item.Status <> X509ChainStatusFlags.OfflineRevocation Then Exit For End If If (item.Status <> X509ChainStatusFlags.NoError) Then msg = msg & Constants.vbCrLf & " -" & item.StatusInformation acceptCertificate = False End If Next item End If End If ' 検証結果が不正だった場合、メッセージボックスを表示します。 If acceptCertificate = False Then msg = msg & Constants.vbCrLf & "接続を続行しますか?" If MessageBox.Show(msg, "セキュリティの警告: サーバーのSSL証明書エラー", _ MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) = System.Windows.Forms.DialogResult.Yes Then acceptCertificate = True End If End If Return acceptCertificate End Function |
C# |
コードのコピー |
---|---|
using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; private void explicitLogin() { // 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 ftp1.Session.RemoteEndPoint.HostNameOrAddress = "myFtpServer"; ftp1.Session.Username = "myUsername"; ftp1.Session.Password = "myPassword"; // データの暗号化を有効にします。 ftp1.Session.Security.EncryptData = true; // Explicit(明示的)モードを指定します。 ftp1.Session.Security.EncryptControl = Dart.Ftp.EncryptControl.Explicit; // サーバーのSSL証明書を検証する際に呼び出されるコールバック・メソッドを指定します。 ftp1.Session.Security.ValidationCallback = remoteCertificateValidation; // FTPサーバーに接続します。 ftp1.Connect(); try { // 設定したユーザー名とパスワードでログインします。 ftp1.Authenticate(); } catch { // SSL証明書の検証結果が不正(false)だった場合は、強制的に接続を閉じます。 ftp1.Abort() } } // サーバーのSSL証明書を検証するメソッドの一例です。 private bool remoteCertificateValidation(Object sender, X509Certificate remoteCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { // 証明書に問題がない場合、trueを返します。 if (sslPolicyErrors == SslPolicyErrors.None) return true; bool acceptCertificate = true; string msg = "このサーバーの証明書には、以下の問題があります。\r\n"; // サーバーが証明書を提示しなかった場合 if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable) { msg = msg + "\r\n - サーバーから証明書が提示されませんでした。\r\n"; acceptCertificate = false; } else { // 証明書の名前が一致しない場合 if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch) { msg = msg + "\r\n - 証明書の名前が一致しませんでした。\r\n"; acceptCertificate = false; } // 証明書に関するその他の問題がある場合 if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors) { foreach (X509ChainStatus item in chain.ChainStatus) { if (item.Status != X509ChainStatusFlags.RevocationStatusUnknown && item.Status != X509ChainStatusFlags.OfflineRevocation) break; if (item.Status != X509ChainStatusFlags.NoError) { msg = msg + "\r\n -" + item.StatusInformation; acceptCertificate = false; } } } } // 検証結果が不正だった場合、メッセージボックスを表示します。 if (acceptCertificate == false) { msg = msg + "\r\n接続を続行しますか?"; if (MessageBox.Show(msg, "セキュリティの警告: サーバーのSSL証明書エラー", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes) acceptCertificate = true; } return acceptCertificate; } |
セキュアなFTPサーバーは、接続時にクライアントへ証明書を要求し、身元の証明を求める場合があります。このプロセスをクライアント認証といいます。
続きを読む
サーバーからクライアントへ証明書の要求があった場合に、ユーザーがローカルシステムにある任意の証明書を選択し、クライアント認証に使用する方法です。
ユーザーが選択した証明書を戻り値として返すメソッドを作成し、そのメソッドをSelectionCallbackフィールドに指定します。サーバーから証明書の要求があったときには、このメソッドが実行され、戻り値として返された証明書がサーバーへ提示されます。
付属サンプルのフォーム「CertificateListForm」では、クライアント認証に使用する証明書をユーザーが選択するUI処理を実現しています。具体的な実装例についてはサンプルをご覧ください。
SelectionCallbackフィールドに指定する、クライアント認証に使用する証明書を返すメソッドは、LocalCertificateSelectionCallbackデリゲート型(System.Net.Security名前空間のクラス)のメソッドです。付属サンプルのLocalCertificateSelectionメソッドでは.NET Framework標準の機能のみを使用して、クライアントの証明書を選択しています。各処理の詳細については、MSDNライブラリなどを参照してください。
サーバーからの要求に対して提示する証明書を、あらかじめ指定しておく方法です。
ローカルシステムの証明書ストアにある任意の証明書を、サーバーとの接続前にCertificatesプロパティ(クライアント証明書のコレクション)にセットしておきます。SelectionCallbackフィールドにメソッドを指定しない場合、サーバーから証明書の要求があったときには、Certificatesプロパティにセットした証明書がクライアント認証に使用されます。
Certificatesプロパティに複数の証明書が存在する場合は、コレクション内の最初の証明書(Certificates[0]またはCertificates(0))がクライアント認証に使用されます。 |
Visual Basic |
コードのコピー |
---|---|
Imports System.Net.Security Imports System.Security.Authentication Imports System.Security.Cryptography.X509Certificates Private Sub explicitLogin() ' 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 Ftp1.Session.RemoteEndPoint.HostNameOrAddress = "MyFtpServer" Ftp1.Session.Username = "myUsername" Ftp1.Session.Password = "myPassword" ' データの暗号化を有効にします。 Ftp1.Session.Security.EncryptData = True ' Explicit(明示的)モードを指定します。 Ftp1.Session.Security.EncryptControl = EncryptControl.Explicit ' サーバーのSSL証明書を検証する際に呼び出されるコールバック・メソッドを指定します。 Ftp1.Session.Security.ValidationCallback = AddressOf remoteCertificateValidation ' 現在のユーザーの"My"証明書ストアを参照します。 Dim store As New X509Store(StoreName.My, StoreLocation.CurrentUser) ' 証明書ストアを読み取り専用で開きます。 store.Open(OpenFlags.ReadOnly) ' ストア内の証明書をCertificatesプロパティにセットします。 Ftp1.Session.Security.Certificates = store.Certificates ' FTPサーバーに接続します。 Ftp1.Connect() ' 設定したユーザー名とパスワードでログインします。 Ftp1.Authenticate() End Sub Private Function remoteCertificateValidation(ByVal sender As Object, ByVal remoteCertificate As X509Certificate, _ ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean ' コードの内容は前述の「SSL証明書を検証せずに接続する」 ' または「SSL証明書を検証した上で接続する」を参照してください。 End Function |
C# |
コードのコピー |
---|---|
using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; private void explicitLogin() { // 接続するFTPサーバー名、ユーザー名、パスワードを設定します。 ftp1.Session.RemoteEndPoint.HostNameOrAddress = "myFtpServer"; ftp1.Session.Username = "myUsername"; ftp1.Session.Password = "myPassword"; // データの暗号化を有効にします。 ftp1.Session.Security.EncryptData = true; // Explicit(明示的)モードを指定します。 ftp1.Session.Security.EncryptControl = EncryptControl.Explicit; // サーバーのSSL証明書を検証する際に呼び出されるコールバック・メソッドを指定します。 ftp1.Session.Security.ValidationCallback = remoteCertificateValidation; // 現在のユーザーの"My"証明書ストアを参照します。 X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); // 証明書ストアを読み取り専用で開きます。 store.Open(OpenFlags.ReadOnly); // ストア内の証明書をCertificatesプロパティにセットします。 ftp1.Session.Security.Certificates = store.Certificates; // FTPサーバーに接続します。 ftp1.Connect(); // 設定したユーザー名とパスワードでログインします。 ftp1.Authenticate(); } private bool remoteCertificateValidation(Object sender, X509Certificate remoteCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { // コードの内容は前述の「SSL証明書を検証せずに接続する」 // または「SSL証明書を検証した上で接続する」を参照してください。 } |