12,964
回編集
287行目: | 287行目: | ||
以下の例では、FTPS (SSL / TLS証明書) を使用して、ASCIIモード (テキストファイル) とバイナリモード (画像ファイル等) で複数のファイルを非同期に送信している。<br> | 以下の例では、FTPS (SSL / TLS証明書) を使用して、ASCIIモード (テキストファイル) とバイナリモード (画像ファイル等) で複数のファイルを非同期に送信している。<br> | ||
<br> | <br> | ||
※注意<br> | <u>※注意</u><br> | ||
実務では、適切なSSL / TLS証明書の検証を行うこと。<br> | <u>実務では、適切なSSL / TLS証明書の検証を行うこと。</u><br> | ||
ファイアウォールやネットワーク設定が、FTPSトラフィック (通常は、990番ポート) を許可していることを確認する。<br> | <u>ファイアウォールやネットワーク設定が、FTPSトラフィック (通常は、990番ポート) を許可していることを確認する。</u><br> | ||
<br> | <br> | ||
また、大量のファイルや大きなファイルを送信する場合は、タイムアウト設定やメモリ使用量に注意する。<br> | <u>また、大量のファイルや大きなファイルを送信する場合は、タイムアウト設定やメモリ使用量に注意する。</u><br> | ||
<br> | <br> | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
334行目: | 334行目: | ||
// SSL / TLS証明書の検証 | // SSL / TLS証明書の検証 | ||
// 注意: 実務では適切に証明書を検証すること | // 注意: 実務では適切に証明書を検証すること | ||
if (!SslCertificateValidator.SetupCertificateValidation()) | |||
{ | |||
return; | |||
} | |||
using (FileStream fileStream = File.OpenRead(localFilePath)) | using (FileStream fileStream = File.OpenRead(localFilePath)) | ||
401行目: | 404行目: | ||
List<(string localFilePath, string remoteFilePath, bool useAscii)> filesToUpload = new List<(string, string, bool)> | List<(string localFilePath, string remoteFilePath, bool useAscii)> filesToUpload = new List<(string, string, bool)> | ||
{ | { | ||
("localTextFile1.txt", "remoteTextFile1.txt", true), | ("localTextFile1.txt", "remoteTextFile1.txt", true), // テキストファイル(ASCIIモード) | ||
("localTextFile2.txt", "remoteTextFile2.txt", true), | ("localTextFile2.txt", "remoteTextFile2.txt", true), // テキストファイル(ASCIIモード) | ||
("localImageFile1.jpg", "remoteImageFile1.jpg", false), // 画像ファイル(バイナリモード) | ("localImageFile1.jpg", "remoteImageFile1.jpg", false), // 画像ファイル(バイナリモード) | ||
("localImageFile2.jpg", "remoteImageFile2.jpg", false) // 画像ファイル(バイナリモード) | ("localImageFile2.jpg", "remoteImageFile2.jpg", false) // 画像ファイル(バイナリモード) | ||
409行目: | 412行目: | ||
// 複数のファイルを同時に送信 | // 複数のファイルを同時に送信 | ||
await ftpsUpload.UploadMultipleFilesAsync(filesToUpload); | await ftpsUpload.UploadMultipleFilesAsync(filesToUpload); | ||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
// ※注意 | |||
// 実務では、使用環境に応じて、さらに厳密な検証ロジックを追加することを推奨する。 | |||
// また、可能な限り信頼された認証局によって発行された証明書を使用することを推奨する。 | |||
// | |||
// 信頼された証明書のリストは定期的に更新して、不要になった証明書は速やかに削除すること。 | |||
using System; | |||
using System.Net.Security; | |||
using System.Security.Cryptography.X509Certificates; | |||
public class SslCertificateValidator | |||
{ | |||
// 信頼された証明書のサムプリント | |||
// 実際の環境に合わせて更新すること | |||
private static readonly string[] TrustedCertificates = new string[] | |||
{ | |||
"A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0", | |||
"B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0U1" | |||
}; | |||
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) | |||
{ | |||
if (sslPolicyErrors == SslPolicyErrors.None) | |||
{ // 証明書チェーンとポリシーエラーが無い場合 | |||
return true; | |||
} | |||
Console.WriteLine($"証明書エラー: {sslPolicyErrors}"); | |||
// 自己署名証明書の場合 | |||
if (sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors) | |||
{ | |||
return ValidateSelfSignedCertificate(certificate); | |||
} | |||
// その他のエラーの場合 | |||
return false; | |||
} | |||
private static bool ValidateSelfSignedCertificate(X509Certificate certificate) | |||
{ | |||
// 証明書のサムプリントを取得 | |||
string certHash = certificate.GetCertHashString(); | |||
// 信頼された証明書リストと照合 | |||
foreach (string trustedHash in TrustedCertificates) | |||
{ | |||
if (certHash.Equals(trustedHash, StringComparison.OrdinalIgnoreCase)) | |||
{ | |||
Console.WriteLine("信頼された自己署名証明書を確認"); | |||
return true; | |||
} | |||
} | |||
Console.WriteLine("未知の自己署名証明書を確認"); | |||
return false; | |||
} | } | ||
} | } |