1

ユーザー/パスワードとその他のデータを保持するテーブルがあります。各レコードのパスワード フィールドは暗号化する必要があります。暗号化に AesCryptoServiceProvider を使用することにし、手動で rgbKey を 1 回作成しました。次に、すべてのユーザー パスワードを暗号化し、パスワード フィールドが rgbKey で暗号化されたテーブルにレコードを挿入しました。

ロード バランサーの背後に複数のサーバーがあり、各サーバーはこれらのレコードを読み取り、パスワード フィールドの値を復号化する必要があります。最初に、base64StringFormat の rgbKey を dll(API) に配置しました。同様に、すべてのサーバーがこの API を使用し、暗号化された値を復号化できます。

ただし、rgbKey を dll ファイルに保持するのは非常に安全ではありません。キーを DPAPI に保持するかどうかについて話し合いました。復号化時に、任意のサーバーで、DPAPI からキーを取得し、暗号化された値を正常に復号化します。

現在のユーザーモードのサーバーで一度だけ保護されたキーを生成し、それを共通のdllに保存できると思いました。共通のdllを使用する各サーバーは、この保護されたキー(byte[])を同じユーザーでDPAPIに与えると、保護されていないキーの値を取得できます。ただし、保護されているマシンでのみ機能し、他のマシンでは「指定された状態での使用に対してキーが無効です」というエラーが発生します。

私の質問は、永続的な rgbKey を保護して、すべてのマシンからアクセスできるようにするにはどうすればよいですか? 以下の同様のテスト コンソール アプリケーションを見てください。私のアプローチの何が問題なのですか?

テスト コンソール アプリケーションのサンプル コードを示します。

まず、ローカル マシンで PDPAPI() 関数を実行します。

    static void PDPAPI() {
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        byte[] rgbKey = encoding.GetBytes( "MyRgbKey" );
        byte[] protectedData = ProtectedData.Protect( rgbKey, null, DataProtectionScope.CurrentUser );
        string base64ProtectedData = Convert.ToBase64String( protectedData );
        Console.WriteLine( "base64ProtectedData:{0}", base64ProtectedData );            
    }

次に、上記の実行から取得した UDPAPI() 関数の base64ProtectedData 値をハードコーディングして追加し、ソリューションを再構築します。

    static void UDPAPI() {
        string base64ProtectedData = "****";
        byte[] protectedData = Convert.FromBase64String( base64ProtectedData );
        byte[] unProtectedData = ProtectedData.Unprotect( protectedData, null, DataProtectionScope.CurrentUser );
        string base64unProtectedData = Convert.ToBase64String( unProtectedData );
        Console.WriteLine( "base64unProtectedData:{0}", base64unProtectedData );
    }            

ローカル マシンで UDPAPI() 関数を実行すると、データの保護が正常に解除されますが、コンソール アプリケーションを他のサーバーに移行し、ネットワーク ユーザーでそのサーバーにログインすると、コンソール アプリケーションで「Key not valid for指定された状態で使用してください。」

4

1 に答える 1

0

正直なところ、パスワードの暗号化では、一方向のハッシュを使用し、パスワードのプレーンテキストを使用する代わりに、ユーザー入力をハッシュして比較するだけで、キーストレージの問題は発生しません。C#で使用する一般的なものは、PBKDF2(Rfc2898DeriveBytes)です。他のオプションについては、暗号化を参照してください:ハッシュ関数がパスワードハッシュに適している理由は何ですか?

キーストレージの問題は常に困難になります。DPAPIは、同じマシン上の他のユーザーからキーを保護できるかなり適切なオプションであり、DLLに保存するよりもはるかに優れていますが、何をしているのかを理解し、実行しているWindowsユーザーのパスワードハッシュ(実際には、パスワードハッシュからのキーの導出、ローテーションなど)。そのため、ローカルマシンから暗号化されたデータをサーバー上で直接使用することはできません。DPAPIを使用するには、サーバーごとにキーを個別に暗号化する必要があります(これは悪いことではありません)。

キーをハードコーディングしないことを常にお勧めします。アクセスできる可能性があるためではなく、必要なときに、または異なる設定で変更する方が簡単だからです。通常、専用のハードウェアなしでできることのほとんどは、キーをデータから分離しておくことです。キーを暗号化することで事態をさらに困難にすることができますが、攻撃者もアクセスする必要のある別のキーを追加するだけであり、理想的な解決策はありません。

時間の経過とともにキーを簡単に変更できるようにする方法が必要な場合は、keyczarフレームワークをc#に移植しました。これには、キーをローテーションするために必要なメカニズムがあり、新しいデータを暗号化しながら古いデータを復号化できますが、そうではありません。キーストレージのアクセシビリティにおいて、セキュリティに関してより賢明なものを実際に提供します。

于 2013-03-14T13:19:02.853 に答える