🔐

C#で公開鍵認証を使ったSFTPファイル転送を実装する方法

に公開

解法

C#で公開鍵認証を使ったSFTPファイル転送機能を実装するには、SSH.NETライブラリを使用します。

必要なパッケージのインストール

Install-Package SSH.NET

基本的な実装

using System;
using System.IO;
using Renci.SshNet;

public class SftpPublicKeyClient
{
    private readonly string _host;
    private readonly int _port;
    private readonly string _username;
    private readonly string _privateKeyPath;
    private readonly string _passphrase;

    public SftpPublicKeyClient(string host, int port, string username, string privateKeyPath, string passphrase = null)
    {
        _host = host;
        _port = port;
        _username = username;
        _privateKeyPath = privateKeyPath;
        _passphrase = passphrase;
    }

    public bool UploadFile(string localFilePath, string remoteFilePath)
    {
        try
        {
            // 秘密鍵の読み込み
            PrivateKeyFile privateKeyFile = string.IsNullOrEmpty(_passphrase)
                ? new PrivateKeyFile(_privateKeyPath)
                : new PrivateKeyFile(_privateKeyPath, _passphrase);

            // 認証方法の設定
            var authMethod = new PrivateKeyAuthenticationMethod(_username, privateKeyFile);
            var connectionInfo = new ConnectionInfo(_host, _port, _username, authMethod);

            // SFTP接続とファイルアップロード
            using (var sftpClient = new SftpClient(connectionInfo))
            {
                sftpClient.Connect();
                
                using (var fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read))
                {
                    sftpClient.UploadFile(fileStream, remoteFilePath);
                }
                
                sftpClient.Disconnect();
                return true;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"エラー: {ex.Message}");
            return false;
        }
    }
}

使用例

// SFTPクライアントの作成
var sftpClient = new SftpPublicKeyClient(
    host: "example.com",
    port: 22,
    username: "your_username",
    privateKeyPath: @"C:\path\to\private_key.pem"
);

// ファイルアップロード
bool success = sftpClient.UploadFile(
    @"C:\local\file.txt", 
    "/remote/path/file.txt"
);

解説

公開鍵認証の仕組み

公開鍵認証では、クライアント側に秘密鍵、サーバ側に対応する公開鍵を配置して認証を行います。パスワード認証と比較してセキュリティが高く、自動化に適しています。

SSH.NETライブラリの特徴

  • .NET Framework/.NET Core両対応
  • RSA、DSA、ECDSA形式の鍵をサポート
  • パスフレーズ付き秘密鍵にも対応
  • SFTP以外にもSSH、SCPもサポート

実装のポイント

1. 秘密鍵の読み込み

PrivateKeyFile privateKeyFile = string.IsNullOrEmpty(passphrase)
    ? new PrivateKeyFile(privateKeyPath)
    : new PrivateKeyFile(privateKeyPath, passphrase);

パスフレーズがある場合とない場合で処理を分岐させます。

2. 接続情報の設定

var authMethod = new PrivateKeyAuthenticationMethod(username, privateKeyFile);
var connectionInfo = new ConnectionInfo(host, port, username, authMethod);

認証方法としてPrivateKeyAuthenticationMethodを使用します。

3. ファイル転送の実行

using (var sftpClient = new SftpClient(connectionInfo))
{
    sftpClient.Connect();
    using (var fileStream = new FileStream(localPath, FileMode.Open, FileAccess.Read))
    {
        sftpClient.UploadFile(fileStream, remotePath);
    }
    sftpClient.Disconnect();
}

using文を使用してリソースの確実な解放を行います。

補足情報

サポートする秘密鍵形式

  • OpenSSH形式(id_rsa, id_dsa, id_ecdsa)
  • PEM形式
  • PuTTY形式(.ppk)※要変換

セキュリティのベストプラクティス

  1. 秘密鍵の適切な管理

    • ファイルの権限を適切に設定
    • パスフレーズの使用を推奨
    • 定期的な鍵の更新
  2. 接続設定の最適化

    • タイムアウト値の設定
    • 接続エラー時のリトライ処理
    • ログ出力での機密情報の除外
  3. エラーハンドリング

    • 詳細なエラーメッセージの出力
    • 適切な例外処理
    • 接続状態の確認

トラブルシューティング

よくある問題と対処法

  1. 接続エラー

    • ホスト名、ポート番号の確認
    • ネットワーク接続の確認
    • ファイアウォール設定の確認
  2. 認証エラー

    • 秘密鍵ファイルのパスの確認
    • 公開鍵がサーバに登録されているか確認
    • パスフレーズの確認
  3. ファイル転送エラー

    • リモートディレクトリの存在確認
    • ファイルの権限確認
    • ディスク容量の確認

この実装により、セキュアで信頼性の高いSFTPファイル転送機能をC#アプリケーションに組み込むことができます。

Discussion