SQL ServerでUNIQUEIDENTIFIERを安全に生成する


15

UNIQUEIDENTIFIERユーザーが特定のデータにアクセスするために使用できるアクセスキーとしてを使用する予定です。その意味で、キーはパスワードとして機能します。

INSERT...SELECTステートメントの一部として、このような識別子を複数生成する必要があります。アーキテクチャ上の理由から、この場合はサーバー側で識別子を生成します。

安全にランダムに生成するにはどうすればよいUNIQUEIDENTIFIERですか?NEWIDセキュリティプロパティがまったく保証されないため、これは十分にランダムではないことに注意してください。推測できないIDが必要なため、SQL ServerのSystem.Security.Cryptography.RandomNumberGeneratorに相当するものを探しています。に基づくものCHECKSUMRANDまたはGETUTCDATE資格がないもの。


2
@AaronBertrand少なくとも、数字が常に1の場合は1つ4。しかし、推測できる可能性があるという強力な証拠がないという事実は、そうではないという意味ではありません。このセキュリティの決定をこの観察に基づいて行うことはできません。
usr

1
たぶんNEWIDは、単に「Debianの弱いSSH鍵」として、ランダムなようである:en.wikinews.org/wiki/...彼らは確かに...それらをテストし、開発者にランダムに見えた
USR

2
この4は、GUIDの生成に使用されるアルゴリズムを示しています。en.wikipedia.org/wiki/Globally_unique_identifier#Algorithm
Mr.Mindor

1
セキュリティのレベルを決定する唯一の要素はビットエントロピーであることを理解していますか?NEWIDがニーズに対して十分にランダムではないという考えは、ユースケースで「セキュア」であるために必要なビットエントロピーの量をある程度知っていることを意味します。その数は何ですか?
ケイドRouxの

2
@usr-「内部状態の完全な知識を与えられた」、任意のアプローチをクラックすることができます。

回答:


26
SELECT CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER)

私が考えていただろうトリックを行う必要があります。

CRYPT_GEN_RANDOM

Crypto API(CAPI)によって生成された暗号乱数を返します。


4

ちょうど2セントですが、これは良い考えではないかもしれません。GUIDのEric Lippertの優れたシリーズ(パート1パート2パート3)を言い換えると、頭字語はGSUIDではなくGUIDであり、グローバルに一意の識別子ではなくグローバルに一意の識別子です。

問題は、NEWID()を使用するすべての人など、非敵意のスコープ内でGUIDが生成されると、すべての値が一意であることが保証されることにあります(まあ、並べ替え、エリックの記事、パート3を参照)。しかし、敵対的なエンティティがそのスコープに入った場合、次の生成されたGUIDを予測するだけでなく、衝突を引き起こすこともできます。

GUIDのように見える構造内に格納する値を生成する独自のメソッドを作成することにより、本質的に敵対的なエンティティになります。GUIDの契約を一意からランダムに変更しました。私よりも数学が上手な人はおそらくあなたがまだユニークであることを証明できますが、それはあなたの生成方法の範囲内にあるだけです。これらの疑似GUIDとNEWID()GUIDを混在させると、すべての賭けはオフになります。

値の使用方法の範囲全体がわからないため、これ良いアイデアでないかもしれません。あなたが値を生成する唯一のエンティティ(ミックスとマッチなし)、および/または値を永続化しない、および/または衝突を気にしない場合、これは問題ではないかもしれません。これらの項目のいずれかが当てはまらない場合は、再評価することができます。


興味深い点。私のデータ型の選択UNIQUEIDENTIFIERはほとんど偶然です。そのタイプを使用して16バイトの量を処理すると便利です。私はそれをパスワードと考えています。ただし、一意である必要があります。衝突が発生することはないと確信しています(アプリがクラッシュしたとしても、それでも安全です)。
usr

私は同意しません、それが「どのように」暗号化されるかは、それが一意ではなくランダムになる場合に依存します。簡単に同じにすることができます。
ダウェシ

4

https://blogs.msdn.microsoft.com/sqlprogrammability/2006/03/23/newsequentialid-histrorybenefits-and-implementation/によると、NEWID()関数はv4スタイルのGUIDを返すWindows関数CoCreateGuidをラップするだけです。 。https://msdn.microsoft.com/en-us/library/bb417a2c-7a58-404f-84dd-6b494ecf0d13#id11によると、1999年のWindows 2000以降、

「Windowsで構築されたすべてのバージョン4 GUIDのランダムビットは、Windows CryptGenRandom暗号化APIまたは同等の、暗号化キーの生成に使用される同じソースを介して取得されます」

だから、少なくとも、それが提供する122ビットのエントロピーの範囲で、暗号的に安全なNEWID()を検討できると思います。


それは面白い。私は個人的にセキュリティの目的でこれを信用しません。WindowsもSQL Serverもこれについて保証しません。
usr

@usr保証がどのようになるかわかりません。「保証」という言葉は使用していませんが、標準のMSDN Windows SDKドキュメントのようです。Windowsの将来のバージョンで、MSがGUIDの暗号ランダム性をダウングレードすることはほとんどありません。得るものは何もないでしょう。
ヨルダンリーガー

そのMSDNページは単に歴史的な選択を文書化していますが、これが将来も保持されるとは言いません。SQL Serverでも同じです。これが崩壊する状況を想像することはできません。しかし、多くの壊滅的なRNG悪徳がありました。このような仮定はしばしば間違っていることが判明しました。これはヒューリスティックな議論です。
usr

@usrしかし、MSDNのドキュメントでWindowsの将来の動作をどのように保証できますか?これらのケースで私たちが期待できる最大のものは、現在の動作の文書化です。動作が変更された場合は、ドキュメントを更新します。そのため、これらのスタックオーバーフローに関するQ&Aにはバージョンタグがあり、随時更新されます。
ジョーダンリーガー

彼らは、変化しないものについて保証します。製品を変更することはできますが、「これらのプロパティを備えたセキュリティクリティカルな機能はここにあります」と言っても変わりません。私は、問題の文書を未来についての声明というよりも歴史的な見解のように解釈します。
usr
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.