22

セキュリティ上の理由から、C# 文字列のメモリ コンテンツをクリアしようとしています。クラスは認識してSecureStringいますが、残念ながら自分のアプリケーションではSecureString代わりに使用できません。Stringクリアする必要がある文字列は、実行時に動的に作成されます (たとえば、文字列リテラルをクリアしようとしていません)。

私が見つけたほとんどの検索結果は、基本的に a の内容をクリアすることStringは不可能であり (文字列は不変であるため)、SecureString使用する必要があると述べています。

したがって、以下の独自の解決策 (安全でないコードを使用) を考え出しました。テストでは解決策が機能することが示されていますが、解決策に何か問題があるかどうかはまだわかりませんか? より良いものはありますか?

static unsafe bool clearString(string s, bool clearInternedString=false) 
{
    if (clearInternedString || string.IsInterned(s) == null)
    {
        fixed (char* c = s)
        {
            for (int i = 0; i < s.Length; i++)
                c[i] = '\0';
        }
        return true;
    }
    return false;
}

編集: GC に関するコメントが呼び出される前に文字列を移動するためclearString: 次のスニペットはどうですか?

string s = new string('\0', len);
fixed (char* c = s)
{
    // copy data from secure location to s
    c[0] = ...;
    c[1] = ...;
    ...

    // do stuff with the string

    // clear the string
    for (int i = 0; i < s.Length; i++)
        c[i] = '\0';
}
4

5 に答える 5

12

標準的な「あなたは安全でない領域に足を踏み入れています」という回答は別として、それ自体が説明できることを願っていますが、次のことを考慮してください。

CLR は、任意の時点で文字列のインスタンスが 1 つだけであることを保証しません。また、文字列がガベージ コレクションされることも保証しません。私が次のことをした場合:

var input = "somestring";
input += "sensitive info";
//do something with input
clearString(input, false);

これの結果は何ですか?(文字列リテラルを使用していないと仮定しましょう。代わりに、これらは何らかの環境からの入力です)

「somestring」の内容で文字列が作成されます。別の文字列が「機密情報」のコンテンツで作成され、さらに別の文字列が「somestringsensitive info」のコンテンツで作成されます。後者の文字列のみがクリアされます。「機密情報」はクリアされません。すぐにガベージ コレクションされる場合とされない場合があります。

機密情報を含む文字列を常に消去するように注意しても、CLR は文字列のインスタンスが 1 つしか存在しないことを保証しません。

編集: 編集 に関しては、文字列をすぐに固定するだけで目的の効果が得られる場合があります。文字列を別の場所などにコピーする必要はありません。上記の文字列を受け取った直後にそれを行う必要がありますが、心配すべきセキュリティ上の問題は他にもあります。たとえば、文字列のソースがそのコピーを ITS メモリに持っていないことを保証することはできません。ソースを明確に理解し、それがどのように機能するかを正確に理解する必要があります。

また、明らかな理由でこの文字列を変更することはできません (変更された文字列が文字列とまったく同じサイズでない限り)。その文字列の一部。

また、自分で書いていない他の関数に渡すと、その関数によってコピーされる場合とコピーされない場合があります。

于 2015-08-27T17:50:54.893 に答える