【C# .NET】App.config の接続文字列を自動暗号化してセキュリティを高める方法

未分類

本ページは広告が含まれています。気になる広告をクリック頂けますと、サーバ運営費になります(^^

C# (.NET Framework) でデスクトップアプリを作成する際、データベースの接続情報(IPアドレス、ID、パスワードなど)をどこに保存していますか?

ソースコードにハードコーディングするのは論外ですが、App.config にそのまま書くと、ビルド後の設定ファイル(Markdown.exe.config など)をメモ帳で開くだけで、**パスワードが丸見え(平文)**になってしまいます。これはセキュリティ上、非常に危険です。

そこで今回は、**「アプリの初回起動時に、設定ファイルを自動的に暗号化する」**というプロフェッショナルな実装方法をご紹介します。

仕組み:DPAPI(データ保護API)とは?

今回使用するのは、.NET Framework が標準で持っている DPAPI (Data Protection API) という仕組みです。

通常の暗号化では「復号するための鍵」をどこかに隠す必要がありますが、DPAPI は 「その Windows マシン(またはユーザー)固有のキー」 を使って暗号化します。

これにより以下のメリットが生まれます。

  1. 鍵の管理が不要: プログラム内に暗号化キーを持つ必要がない。
  2. 盗難に強い: 万が一、暗号化された設定ファイルだけを USB メモリ等で盗まれても、別のパソコンでは復号できないため、パスワードは解読されません。

実装手順

1. 参照の追加

まず、App.config をプログラムから書き換えるために、プロジェクトの参照設定に System.Configuration を追加してください。

2. App.config の準備

開発段階では、通常通り平文で記述します。 ※ providerName は使用するDBに合わせて変更してください(PostgreSQLなら Npgsql、SQL Serverなら System.Data.SqlClient)。

XML

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="MyDatabaseContext" 
         connectionString="Host=192.168.1.10;Port=5432;Username=my_user;Password=MyStrongPassword!;Database=MyDB"
         providerName="Npgsql" />
  </connectionStrings>
</configuration>

3. 自動暗号化ロジックの実装

アプリの起動時(MainWindow のコンストラクタや App.xaml.csOnStartup など)に呼び出すメソッドを作成します。

このコードは、設定ファイルを確認し、**「まだ暗号化されていなければ暗号化して保存する」**という動作をします。

C#

using System.Configuration; // これが必要です

// ... (クラス内)

/// <summary>
/// App.configの接続文字列セクションを安全に暗号化します
/// </summary>
private void SecureConnectionStrings()
{
    try
    {
        // 現在のアプリケーションの設定ファイルを開く
        Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        ConnectionStringsSection section = config.ConnectionStrings;

        // まだ暗号化されていない場合のみ実行
        if (section != null && !section.SectionInformation.IsProtected)
        {
            // "DataProtectionConfigurationProvider" (DPAPI) を使用して暗号化
            section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");

            // 保存して設定を再読み込み不要にする強制保存
            section.SectionInformation.ForceSave = true;
            config.Save(ConfigurationSaveMode.Full);
        }
    }
    catch (Exception ex)
    {
        // 権限不足などで暗号化に失敗しても、アプリ自体は動くようにログ出力等にとどめる
        System.Diagnostics.Debug.WriteLine($"設定ファイルの暗号化に失敗: {ex.Message}");
    }
}

4. 呼び出しとデータの取得

このメソッドを呼んだ後は、以下のように通常通りアクセスするだけで、.NET が自動的に復号してくれます。

C#

public MainWindow()
{
    InitializeComponent();
    
    // 起動時にセキュリティ化を実行
    SecureConnectionStrings();
}

private void ConnectDb()
{
    // 暗号化されていても、コード上は意識せず通常通り取得可能
    string connStr = ConfigurationManager.ConnectionStrings["MyDatabaseContext"].ConnectionString;
    
    // DB接続処理...
}

デプロイ(配布)する方法

この仕組みを使う場合、配布手順には少しコツがあります。

「開発者のPCで暗号化したファイルを、そのままユーザーに渡してはいけません」

なぜなら、前述の通りこの暗号化は「そのマシン固有のキー」を使うため、開発機で暗号化したファイルは、ユーザーのPCでは復号できずにエラーになるからです。

正しい配布フロー

  1. 配布時: インストーラーや配布zipファイルには、「平文(パスワードが見える状態)」の App.config を含めます。
  2. インストール後: ユーザーが初めてアプリを起動します。
  3. 初回起動時: 上記の SecureConnectionStrings() が走り、ユーザーのPC上のキーを使って設定ファイルが暗号化され、上書き保存されます。
  4. 2回目以降: 既に暗号化されているため、そのまま安全に利用されます。

これにより、開発者の手を煩わせることなく、運用環境でのセキュリティを担保することができます。

注意点

アプリを Program Files フォルダ等にインストールする場合、アプリ自身が設定ファイルを書き換えるために「管理者権限」が必要になることがあります。その場合は、マニフェストファイルで権限レベルを上げるか、設定ファイルの保存場所を AppData 等に変更する工夫が必要になる場合があります。

開発中、うっかり暗号化してしまった場合(一番カンタンな方法)

Visual Studio の仕組み上、「ソースコードにある App.config「ビルドされて実行される bin\Debug\アプリ名.exe.config は別物です。

アプリを実行して暗号化されるのは、bin フォルダの中にあるファイルだけです。 プロジェクト直下にある元の App.config は暗号化されません。

ソリューションエクスプローラー上で、App.confを選択、出力ディレクトリにコピーを、新しい場合はコピーするを選択して、いったん、debugフォルダ内にあるプログラム名.config は削除しておきます。

「Visual Studio で『リビルド』する」 すると、元のきれいな平文の App.configbin フォルダに上書きコピーされ、元通りになります。

  • 「開発中にアプリを動かしたら暗号化されてしまい、中身が見えなくなった!」と焦る必要はありません。Visual Studio で「リビルド」すれば、ソース元の平文ファイルが上書きされるので元に戻ります。

さらに注意、

この方法ですと、平分のApp.config も、Debugディレクトリに出力されるため削除しておきましょう。

タイトルとURLをコピーしました