我想对数据库中的敏感数据使用加密安全主键 - 这是无法猜测/可预测的,并且它不能由数据库生成(我需要在持久化对象之前使用密钥)。
我理解Java使用带有加密安全随机数生成器的类型4 UUID,但是我知道UUID并不是完全随机的,所以我的问题是假设无法从一组现有的Uuid中预测uuids是多么安全?
答案 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 (或其他?)方法插入。
如果你让我们知道你决定走哪条路,那会很酷。