web-dev-qa-db-fra.com

Java UUID aléatoire est-il prévisible?

Je voudrais utiliser une clé primaire cryptographiquement sécurisée pour les données sensibles dans une base de données - cela ne peut pas être devinable/prévisible et il ne peut pas être généré par la base de données (j'ai besoin de la clé avant que l'objet ne persiste).

Je comprends Java utilise un UUID de type 4 avec un générateur de nombres aléatoires sécurisé cryptographiquement, mais je sais que l'UUID n'est pas complètement aléatoire, donc ma question est de savoir à quel point il est sûr de supposer que les uuides ne peuvent pas être prédits à partir d'un ensemble de ceux existants?

40
ant-depalma

Eh bien, si vous voulez savoir à quel point un UUID est aléatoire, vous devez regarder la source.

La section de code suivante est tirée de OpenJDK7 (et elle est identique dans 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);
    }

Comme vous pouvez le voir, seulement 2 octets sur 16 ne sont pas complètement aléatoires. Dans le sixième octet, vous perdez 4 bits sur 8 et sur l'octet 8, vous perdez 2 bits de caractère aléatoire.

Par conséquent, vous obtiendrez une valeur de 128 bits avec un caractère aléatoire de 122 bits.

Le seul problème qui peut résulter de la manipulation est qu'avec une grande chance vos données peuvent être identifiées comme UUID. Par conséquent, si vous souhaitez le masquer dans d'autres données aléatoires, cela ne fonctionnera pas ...

33
Robert

Si vous souhaitez générer une clé aléatoire sécurisée, je vous suggère d'utiliser SecureRandom. Cela peut générer une clé de n'importe quel nombre de bits dont vous avez besoin. C'est plus lent que Random, mais beaucoup plus sûr.

3
Peter Lawrey

J'ai toujours pensé que le `` générateur de nombres aléatoires cryptographiquement sécurisé '', (en fait `` générateur de nombres pseudo aléatoires cryptographiquement fort '') Javadoc note répond à cela.

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

D'après ce que Wikipedia dit http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator une telle prédiction serait un algorithme non polynomial.

Si vous avez besoin de quelque chose de "vraiment" et pas seulement de "pseudo" aléatoire, vous devez utiliser quelque chose d'extérieur, un générateur de bruit matériel, des points aléatoires générés après avoir déplacé une souris, ...

EntropyPool semble aider à cela, je ne l'ai pas encore essayé http://random.hd.org/ La manière Je le comprends, cela vous permet de télécharger du bruit réel et de l'utiliser dans votre application Java. Ce n'est pas connecté à Java.util.UUID api, cependant, pourrait probablement être branché en utilisant la méthode nameUUIDFromBytes (ou autre?).

Ce serait cool si vous nous faites savoir dans quelle direction vous avez décidé d'aller.

2
MarianP