web-dev-qa-db-ja.com

SecureStringはどのように「暗号化」され、引き続き使用できますか?

MSDNによると SecureString コンテンツは暗号化されているため、プログラムがディスクにスワップされた場合、文字列のコンテンツは暗号化されません。においを嗅ぐ。

このような暗号化はどのように可能でしょうか?アルゴリズムは固定されているため、よく知られているか控除可能であり(たとえば、業界のアルゴリズムで広く使用されている7つのうちの1つ)、プログラムのどこかにキーが必要です。したがって、攻撃者は暗号化された文字列をフェッチし、キーをフェッチしてデータを復号化する可能性があります。

このような暗号化はどのように役立ちますか?

36
sharptooth

キーの導出に使用される [〜#〜] dpapi [〜#〜] に関する記事から引用しています。これは、SecureStringについてのほとんどの質問に答えるはずです。

はい、SecureStringには欠点があり、完全に安全ではありません。データにアクセスする方法があります。たとえば、プロセスに Hawkeye を挿入する方法は、SecureStringを抽出する方法としてMSDNで言及されています。私はこの主張を個人的に検証していません。

DAPIキー管理

DAPIは対称ベースの暗号化技術です。つまり、データの暗号化と復号化の両方に同じキーを使用します。 DAPIの使用方法の例をいくつか紹介する前に、DAPIがキーを管理する方法について説明する価値があります。ほとんどの場合、DAPIキー管理プロセスは目に見えず、通常は心配する必要はありません。これが、DAPIが優れたアプローチである主な理由です。

はじめに、マスターキーはユーザーのログインパスワードから生成されると書きました。これは全体像ではありません。実際に発生するのは、Windowsがユーザーのログインパスワードを使用してマスターキーを生成することです。このマスターキーは、ユーザーのパスワードを使用して保護され、ユーザーのプロファイルとともに保存されます。次に、このマスターキーは、他の多くのキーを導出するために使用され、データを保護するために使用されるのはこれらの他のキーです。

Windowsがこれを行う理由は、アプリケーションが個々のキーを生成するプロセスにエントロピーと呼ばれる追加情報を追加できるようにするためです。ユーザーのログインアカウントで実行されているすべてのアプリケーションが同じキーを使用しているかどうかを確認すると、すべてのアプリケーションがDAPIで保護されたデータの保護を解除できます。アプリケーションがDAPIで保護されたデータを共有できるようにしたい場合があります。ただし、そうしない場合もあります。アプリケーションにキーの生成にエントロピーを提供させることにより、そのキーはアプリケーション固有になり、そのアプリケーションによって保護されているデータは、エントロピーを知っている場合にのみ再び保護を解除できます。

マスターキーを生成し、そのマスターキーを使用して他のキーを生成して実際の暗号化を行うことは、長い道のりのように思えるかもしれませんが、大きな利点が1つあります。ユーザーパスワードで保護されたマスターキーとデータを保護するために使用される実際のキーの間には追加レベルの抽象化があるため、ユーザーがパスワードを変更すると、マスターキーのみを再保護する必要があります。保護されたデータを再保護する必要はありません。マスターキーのサイズはデータよりもはるかに小さいため、パフォーマンスが大幅に節約されます。

ユーザーのパスワードが変更されると、もちろん新しいマスターキーが生成されます。次に、この新しいマスターキーを使用して、新しい個別のキーを生成します。ただし、以前に生成されたすべての個別のキーは古いマスターキーから派生したため、Windowsは以前のすべてのマスターキーを保存する必要があります。 Windowsはマスターキーを決して忘れず、保護されたすべてのデータはGUIDでマークされ、データを保護するために使用されたマスターキーを示します。したがって、適応性の観点から、DAPIはユーザーの変更に対応できます。 'パスワード、a)保護されたデータを再保護する必要がないこと、b)以前にデータを引き続き利用可能として保護するために使用されたキー、およびc)これをすべて自動的に行うことを保証します。

コンピューターがドメインのメンバーでない限り、DAPIは、保護に使用されたのと同じマシン上の保護されていないデータのみを使用できます。

DAPIは、マスターキーがユーザーパスワードに基づいており、あるユーザーの保護されたデータを別のユーザーが保護解除できないというユーザーレベルの保護を可能にするだけでなく、マスターキーがマシン固有の情報に基づいているというマシンレベルの保護も提供します。マシンレベルのマスターキーを使用すると、アプリケーションは保護されたデータを保存できるため、アプリケーションのすべてのユーザーが保護を解除できます。すでに説明したプロセスの唯一の違いは、マスターキーがユーザー固有の情報ではなくマシン固有の情報から生成されることです。

19
NetSquirrel

私はそのコードのある時点を調べましたが、Windowsのadvapi32を使用して汚い作業を行っています。したがって、キーはアプリケーションのメモリに保存されません。

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static int SystemFunction040([In, Out] SafeBSTRHandle pDataIn, [In] uint cbDataIn, [In] uint dwFlag)

これは RtlEncryptMemory としてよく知られています

RtlDecryptMemorySystemFunction041)で復号化します。

コンパイラはSecurityCriticalAttributeでも何かをするはずです。

editこれは4.0を使用して反映されました。他のバージョンは異なる可能性があります

11
Daniel A. White

他の人がすでに答えているように、SecureStringの内容はDPAPIを使用して暗号化されているため、キーはアプリケーションに保存されず、OSの一部です。私は100%肯定的ではありませんが、SecureStringはユーザー固有のキーを使用していると思います。そのため、別のプロセスがメモリブロックにアクセスした場合でも、同じ資格情報で実行する必要があります。 DPAPIを使用してコンテンツを単純に復号化するため。そうでない場合でも、マシンキー(理論上)は、別のシステムに転送された場合に文字列が簡単に復号化されるのを防ぎます。

SecureStringでさらに重要なのは、いつどのように使用するかです。これは、「延長された」期間メモリに保持する必要があるが、復号化された形式では頻繁に必要とされない文字列データを格納するために使用する必要があります。ある時点で、それを通常の古いSystem.StringまたはSystem.Char[]に復号化する必要があります。これは、メモリ内で最も脆弱な場合です。これを頻繁に行うと、復号化された文字列の複数のコピーがメモリ内に浮かんでいて、収集されるのを待っています。

原則として、使用頻度が低い場合(PaypalやAmazon APIの操作など)に保持する必要のある暗号化されたデータ(ログイン認証情報など)を読み取る場合は、それらの認証情報をSecureStringとして保存/キャッシュします。 、次に、必要に応じてWebサービス呼び出しを行うのに十分な時間だけ復号化し、復号化されたコピーの寿命が数行のコードであることを確認します。

メモリがキャッシュまたはスワップされる前に復号化されたコピーが収集される可能性を高めるために、復号化された文字列の使用中にコンテキストスイッチを行わないことをCLRに示唆する重要なブロックなどを使用することもおそらく賢明です。

7
Toby

DPAPIの魔法によって:

このクラスは、データ保護API(DPAPI)で保護されたメモリモデルを使用してデータを格納します。つまり、データはSecureString内に保存されている間、常に暗号化された形式になっています。暗号化キーはローカルセキュリティ機関サブシステム(LSASS.EXE)によって管理され、DPAPIを介して、プロセス間通信を介してデータを復号化できます。

2
Steve Morgan