したがって、めったに使用されないように見えるこのクラスがあります: SecureString 。少なくとも2.0から出回っており、SOの質問がいくつかありますが、私は自分自身の特定の質問をしたいと思いました。
LoginFormがあります。ユーザー名と(マスクされた)パスワードフィールドを含む単純なWinFormsダイアログ。ユーザーが両方を入力して[ログイン]をクリックすると、情報はキーストレッチのレイヤーを実行する挿入された認証クラスに渡され、検証のためにストレッチされたキーの半分をハッシュし、残りの半分は暗号化されたユーザーの対称キーですアカウントデータ。これがすべて完了すると、loginFormが閉じられ、オーセンティケータークラスが破棄され、システムはメインフォームのロードに進みます。かなり標準的なもので、標準のhash-the-password-and-compareよりも少し複雑かもしれませんが、私の場合、単純なハッシュパスワードは、ユーザーデータをプレーンテキストで保存することで無効になります。パーティーシステム(そして私たちは皆、人々がパスワードを再利用する方法を知っています)。
これが最初の質問です。 SecureStringを使用してパスワードテキストボックスからパスワードを取得するにはどうすればよいですかなしテキストボックスのTextプロパティを介して通常のSystem.Stringとして公開されますか? CLRクラスによってラップされているテキストボックスのアンマネージGDIウィンドウにアクセスし、Marshalクラスを使用してテキストデータをプルする方法があると思います。方法がわかりません。そして、私は良い情報を見つけることができないようです。
これが2番目の質問です。 SecureStringとしてパスワードを取得したら、System.Security.Crypto名前空間からハッシュプロバイダーにパスワードを渡すにはどうすればよいですか?私の推測では、Marshal.SecureStringToBSTR()を使用してから、返されたIntPtrからバイト配列に戻るMarshal.Copy()を使用します。次に、Marshal.ZeroBSTR()を呼び出してアンマネージメモリをクリーンアップし、ハッシュを取得したらArray.Clear()を使用してマネージ配列をゼロにすることができます。メモリの管理されたコピーの存続期間を完全に制御できるよりクリーンな方法がある場合は、教えてください。
3番目の質問;これは本当に必要なことですか、それともマネージドメモリ環境におけるSystem.Stringの固有の不安定さは少し誇張されていますか?暗号化されているかどうかに関係なく、パスワードの保存に使用されるものはすべてshouldスコープ外であり、OSがアプリを仮想メモリにスワップすることを検討するずっと前にガベージコレクターに向かう途中です(パスワードをスニッフィングできるようにする)コンピュータのハードシャットダウン後のスワップファイルから)。コールドブート攻撃は理論的な可能性ですが、実際、これはどのくらい一般的ですか?より大きな懸念は、現在復号化されているユーザーデータです。これは、アプリケーションの存続期間全体にわたってユーザーの一部として存在します(したがって、いくつかの基本的な使用法を除いて、SecureStringsを使用するための主要な候補となります)。
SecureString
が必要だと思われる場合は、攻撃者がプロセスメモリも読み取ることができると信じる必要があります。後者が当てはまる場合、入力時にパスワード文字を読み取るか、テキストボックスの内部文字バッファーから直接読み取るか、画面からピクセルを読み取ることができます。
これは非現実的なシナリオです。 SecureString
は使用しないでください。それはほとんど役に立たず、あなたの時間を盗みます。
コールドブート攻撃はより現実的ですが、非常にまれです。それらは、通常完全にマシンを所有する物理的なマシンアクセスを必要とします。 攻撃者による読み取りは、この場合の懸念事項の中で最も少ないものです。
基本的に、開発者時間がSecureString
を使用して十分に費やされている場合を考え出す必要があります。
まず第一に、私はusrに同意することを述べたいと思います-気にしないでください。
ここで詳細に: