.Net GUIDはどの程度確定的ですか?
質問
昨日 GUIDを尋ねましたセッションIDとして安全に使用できるWindows 2003上で生成されたものと、この記事と組み合わせた回答 GUIDはグローバルに一意ですが、GUIDの部分文字列がではないため、CookieのセッションIDとしてGUIDを使用する現在のメカニズムを置き換えることを検討するよう促されました。
その変更を行うのは少し手間がかかるため、Vista PCでクイックGUIDテストを実行して、GUIDのシーケンスが明らかに決定的であるかどうかを確認することにしました(心配しているのは、攻撃者がサーバーによって生成されたGUIDのシーケンス(新しい一致するGUIDを生成できます)。
Raymond Chenの記事(この非常に古い仕様を参照) UUIDとGUID 1998年から)GUIDは次のもので構成されています:
- 60ビットのタイムスタンプ、
- 48ビットのコンピューター識別子、
- 14ビットのuniquifier、および
- 6ビットが修正されました
10個のGUIDを生成する場合、最初の15個のASCII文字(「-」を除く)はタイムスタンプ、次の12個のASCII文字はコンピューター識別子、次の3.5個のASCII文字はランダムで、最後の1.5文字は固定です。
.Net System.Guid.NewGuid()を使用してVista PCで10個のGUIDを取得すると、次の結果が得られます。
b4e95ead-3619-4dc2-9102-cf7ab0efd927
a45ee719-decd-46b2-8355-7becbe406f74
9af68d75-35a0-4907-b6ab-f15e33acfe96
bed88fa3-3209-4a19-97dd-85d5428ea5f4
123cb39b-8d81-41c6-8894-f1257a8f7606
e2b1f6b1-5791-4a18-80a9-5dc668574ecb
c52aa660-2629-4659-bb83-5583081e5a1c
76eda32d-ceda-412e-8ade-30c47416e954
cbc4d45e-7281-40d2-9f90-00539b04fe98
be36524c-267c-4791-bc9e-3c20b29d7615
簡単な目視検査で識別できる唯一のパターンは、13番目のASCII文字が常に4であることです。
再び、System.Guidに依存して擬似ランダムセッションIDを生成することで、セッションIDのクラッキングが数千ドルの価値があるWebアプリケーションを保護するのに十分であるかどうか疑問に思っています。
更新:GUIDを使用する代わりに、以下のアプローチを使用してセッションIDを生成する予定です。 HTTP Cookieでの使用に適したように、384ビットの乱数を0x00バイトの文字列に変換しています。
RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider();
byte[] myKey = new byte[48];
rngProvider.GetBytes(myKey);
string sessionID = null;
myKey.ToList().ForEach(b => sessionID += b.ToString("x2"));
Console.WriteLine(sessionID);
解決
完全な答えではありませんが、GUID(id est、v4)の生成に使用されるアルゴリズムのバージョンを示すため、13番目の16進数は常に4です。また、私はウィキペディアを引用します:
WinAPI GUIDの暗号化分析 ジェネレーターは、 V4 GUIDのシーケンスは擬似ランダムです。 初期状態が与えられると 次の250 000 GUIDまで予測する UuidCreate関数によって返されます。 これがGUIDを使用すべきではない理由です 暗号化、たとえばランダムキーとして。
記事の残りの部分とその参照: http://en.wikipedia.org/wiki/ガイド
-編集-
セキュリティの観点から、セッションIDを好きなように生成し、暗号化して署名することをお勧めします。そのようにして、必要な情報をすべて詰め込み、最後に署名をたたくことができます-考えられる問題は、キーのサイズ/強度と、結果として生じるCookieのサイズとのトレードオフです。 GUIDはIDとして役立ちますが、セキュリティには専用の暗号化技術のみを使用します。
他のヒント
を使用することをお勧めしますSystem.Security.Cryptography.RandomNumberGenerator 。これは、リバースエンジニアリングできない数値を生成するように設計されています。 Guidの動機はユニークであることです。 GUIDと安全な乱数の両方を組み合わせることができますが、128ビットの安全な乱数が実際に衝突することはありません。
注意事項:
- GUIDの実装は、暗号学的に安全であるように設計されているとは思いません。 (そして、この仮定は、次の項目にリンクされた記事によって裏付けられます。)
- 13番目のASCII文字は、 GUIDの生成に使用されたアルゴリズム。
強力なセッションIDを使用することに本当に関心がある場合は、おそらく、マシン外から判断できない何かの暗号的に安全なハッシュが最善のアプローチでしょう。おそらく、いくつかの内部ドキュメントまたはデータソースからワンタイムパッドを生成することもできます。
何をしようとしていますか?乱数のソースだけが必要ですか?
random.org およびホットビット。何年も前に、これらのソースから数値を収集し、それらを結合して、非常に美しいランダムシリーズを取得するJavaライブラリがありました(ただし、2つのサイトがcahootzにないことを前提としています)。
簡単な答えは、セッションIDの推測やクラッキングを防止したい場合、セッションIDを生成するのに十分な強度のGUIDはありません。
AESキーとしてGUIDを使用したくないのと同じ理由で、機密IDの種類にGUIDを使用したくない。
GUIDは、数学的に保証された一意のIDであり、繰り返されることはありません。
セッションIDを解読する価値は$ 1000に過ぎないとしても、それが100回行われると想像してください。今、あなたは真剣なブリンブリンを話している。
GUIDを使用するのは簡単な方法ですが、抵抗し、アプリケーションを適切に保護するために適切な予防措置を講じることで痛みに対処します。ユーザーに感謝します。
取得する可能性を考慮すると、重複したGUIDを取得することはほとんど不可能です。ここにいくつかの簡単な数学の事実があります
世界の砂粒75,000,000,000,000,000,000
GUIDの数340,282,366,920,938,463,463,374,607,431,770,000,000