web-dev-qa-db-ja.com

JavaランダムなUUIDは予測可能ですか?

データベース内の機密データに暗号で保護された主キーを使用したい-これは推測/予測できず、データベースで生成できない(オブジェクトが保持される前にキーが必要)。

Javaは暗号化された安全な乱数ジェネレータでタイプ4 UUIDを使用しますが、UUIDは完全にランダムではないことを知っているので、uuidを予測できないと想定するのはどれほど安全かという質問です既存のものから?

40
ant-depalma

UUIDがどれほどランダムかを知りたい場合は、ソースを調べる必要があります。

次のコードセクションは OpenJDK7 から取得されます(そして OpenJDK6 でも同じです):

public static UUID randomUUID() {
        SecureRandom ng = numberGenerator;
        if (ng == null) {
            numberGenerator = ng = new SecureRandom();
        }

        byte[] randomBytes = new byte[16];
        ng.nextBytes(randomBytes);
        randomBytes[6]  &= 0x0f;  /* clear version        */
        randomBytes[6]  |= 0x40;  /* set to version 4     */
        randomBytes[8]  &= 0x3f;  /* clear variant        */
        randomBytes[8]  |= 0x80;  /* set to IETF variant  */
        return new UUID(randomBytes);
    }

ご覧のとおり、16バイトのうち2バイトのみが完全にランダムではありません。 6番目のバイトでは8ビットのうち4ビットが失われ、バイト8では2ビットのランダムさが失われます。

したがって、128ビットのランダム性を持つ128ビットの値が得られます。

操作から発生する可能性のある唯一の問題は、データがUUIDとして識別される可能性が高いことです。したがって、他のランダムデータで非表示にしたい場合、これは機能しません...

33
Robert

安全なランダムキーを生成する場合は、SecureRandomを使用することをお勧めします。これにより、必要なビット数のキーを生成できます。ランダムよりも低速ですが、はるかに安全です。

3
Peter Lawrey

私は「暗号的に安全な乱数ジェネレータ」(実際には「暗号的に強力な疑似乱数ジェネレータ」)のJavadocノートがこれに答えるといつも思っていました。

http://download.Oracle.com/javase/1,5.0/docs/api/Java/util/UUID.html#randomUUID ()

ウィキペディアの発言から http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator このような予測は非多項式アルゴリズムになります。

「疑似」ランダムだけでなく「本当に」何かが必要な場合は、外部の何か、ハードウェアノイズジェネレーター、マウスを動かした後に生成されるランダムポイントなどを使用する必要があります。

EntropyPoolはそれを助けているようですが、まだ試していません http://random.hd.org/ 方法私はそれを理解しています、それはあなたにいくつかの現実世界のノイズをダウンロードしてあなたのJavaアプリでそれを使用させます。それはそうではありませんただし、Java.util.UUID APIに接続されている場合は、おそらくnameUUIDFromBytes(またはその他?)メソッドを使用してプラグインできます。

あなたがどちらに行くことに決めたのかを私たちに知らせたらクールです。

2
MarianP