Java随机UUID是否可预测?

时间:2011-09-23 17:35:35

标签: java security random uuid

我想对数据库中的敏感数据使用加密安全主键 - 这是无法猜测/可预测的,并且它不能由数据库生成(我需要在持久化对象之前使用密钥)。

我理解Java使用带有加密安全随机数生成器的类型4 UUID,但是我知道UUID并不是完全随机的,所以我的问题是假设无法从一组现有的Uuid中预测uuids是多么安全?

3 个答案:

答案 0 :(得分:33)

如果您想了解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个不是完全随机的。在第六个字节中,您将丢失4个中的4个,在字节8上,您将丢失2位随机性。

因此,您将获得具有122位随机性的128位值。

操作可能产生的唯一问题是,您的数据很有可能被识别为UUID。因此,如果您想将其隐藏在其他随机数据中,这将无效......

答案 1 :(得分:3)

如果您想生成安全的随机密钥,我建议您使用SecureRandom。这可以生成您需要的任意位数的密钥。它比随机慢,但更安全。

答案 2 :(得分:2)

我一直认为'加密安全的随机数生成器',(实际上是'密码强的伪随机数生成器')Javadoc note会回答这个问题。

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 (或其他?)方法插入。

如果你让我们知道你决定走哪条路,那会很酷。