Java Language Génération de nombres pseudo-aléatoires sécurisés par cryptographie


Exemple

Random et ThreadLocalRandom sont assez bons pour un usage quotidien, mais ils ont un gros problème: ils sont basés sur un générateur de congruence linéaire , un algorithme dont la sortie peut être prédite assez facilement. Ainsi, ces deux classes ne conviennent pas aux utilisations cryptographiques (telles que la génération de clés).

On peut utiliser java.security.SecureRandom dans les situations où un PRNG avec une sortie très difficile à prévoir est requis. Prédire les nombres aléatoires créés par les instances de cette classe est suffisamment difficile pour étiqueter la classe comme étant sécurisée sur le plan cryptographique .

import java.security.SecureRandom;
import java.util.Arrays;

public class Foo {
    public static void main(String[] args) {
        SecureRandom rng = new SecureRandom();
        byte[] randomBytes = new byte[64];
        rng.nextBytes(randomBytes); // Fills randomBytes with random bytes (duh)
        System.out.println(Arrays.toString(randomBytes));
    }
}

En plus d'être sécurisé sur le plan cryptographique, SecureRandom dispose d'une période gigantesque de 2 160 , contre 2 48 pour la période Random . Il a cependant l’inconvénient d’être beaucoup plus lent que Random et d’autres PRNG linéaires tels que Mersenne Twister et Xorshift .

Notez que la mise en œuvre de SecureRandom dépend à la fois de la plate-forme et du fournisseur. Le SecureRandom par défaut (fourni par le fournisseur SUN dans sun.security.provider.SecureRandom ):

  • sur des systèmes de type Unix, dotés de données provenant de /dev/random et / ou /dev/urandom .
  • sur Windows, doté d'appels à CryptGenRandom() dans CryptoAPI .