Les applications Java peuvent et doivent utiliser la classe java.security.SecureRandom pour produire des valeurs aléatoires cryptographiquement fortes en utilisant un générateur de nombres pseudo-aléatoires cryptographiquement fort ( CSPRNG ). Les implémentations JDK standard de la classe java.util.Random ne sont pas considérées comme cryptographiquement solides.
Les systèmes d'exploitation de type Unix ont /dev/random
un fichier spécial qui sert des nombres pseudo aléatoires accédant au bruit environnemental collecté à partir des pilotes de périphériques et d'autres sources. Cependant, il bloque s'il y a moins d'entropie disponible que demandé ; /dev/urandom
ne bloque généralement jamais, même si la graine du générateur de nombres pseudo-aléatoires n'a pas été complètement initialisée avec l'entropie depuis le démarrage. Il y a toujours un troisième fichier spécial, /dev/arandom
qui se bloque après le démarrage jusqu'à ce que la graine ait été correctement initialisée avec suffisamment d'entropie, puis ne se bloque plus jamais.
Par défaut, la JVM amorce la classe SecureRandom en utilisant /dev/random
, par conséquent, votre code Java peut se bloquer de manière inattendue . L'option -Djava.security.egd=file:/dev/./urandom
de l'invocation de ligne de commande utilisée pour démarrer le processus Java indique à la JVM d'utiliser à la /dev/urandom
place.
Le supplément /./
semble inciter la JVM à utiliser l' algorithme SHA1PRNG qui utilise SHA-1 comme base du PRNG (Pseudo Random Number Generator). Il est plus fort que l'algorithme NativePRNG utilisé lorsque /dev/urandom
est spécifié.
Enfin, il existe un mythe qui /dev/urandom
est un générateur de nombres pseudo-aléatoires, un PRNG, alors qu'il /dev/random
est un "vrai" générateur de nombres aléatoires . Ce n'est tout simplement pas vrai, les deux /dev/random
et /dev/urandom
sont alimentés par le même CSPRNG (générateur de nombres pseudo-aléatoires cryptographiquement sécurisé). Seul le comportement lorsque leur pool respectif est à court d'entropie, selon certaines estimations, diffère: les /dev/random
blocs, tandis /dev/urandom
que non.
Qu'en est-il de l'entropie faible? Ça n'a pas d'importance.
Il s'avère que «regarder au hasard» est l'exigence de base pour beaucoup de nos blocs de construction cryptographiques. Et si vous prenez la sortie d'un hachage cryptographique, il doit être impossible de la distinguer d'une chaîne aléatoire pour que les chiffrements l'acceptent. C'est la raison d'utiliser l'algorithme SHA1PRNG, car il utilise une fonction de hachage et un compteur, avec une graine.
Quand est-il censé être appliqué?
Je dirais toujours.
Sources:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom
EDIT 04/2020:
Un commentaire mentionne une modification du comportement de la classe SecureRandom dans Java 8.
SHA1PRNG et NativePRNG ont été corrigés pour respecter correctement les propriétés de la source de départ SecureRandom dans le fichier java.security. (La solution de contournement obscure utilisant file: /// dev / urandom et file: / dev /./ urandom n'est plus nécessaire.)
Cela avait déjà été souligné par les tests référencés dans la section Sources ci-dessus. L'extra /./
est nécessaire pour changer l'algorithme utilisé par SecureRanom dans Java 8 de NativePRNG à SHA1PRNG.
Cependant, j'ai des nouvelles que j'aimerais partager. Selon le JEP-273 , depuis Java 9, la classe SecureRandom implémente les trois mécanismes du générateur de bits aléatoires déterministes (DRBG) décrits dans le NIST 800-90Ar1 . Ces mécanismes implémentent des algorithmes modernes aussi puissants que SHA-512 et AES-256.
Le JDK avait deux types d' implémentations SecureRandom :
- L'un est dépendant de la plate-forme et basé sur des appels natifs ou des appareils OS tels que la lecture
/dev/{u}random
sur Unix ou l'utilisation de CryptoAPI sur Windows. Les dernières versions de Linux et Windows prennent déjà en charge DRBG, mais les versions plus anciennes et les systèmes intégrés ne le sont peut-être pas .
- L'autre type est une implémentation Java pure qui utilise une ancienne implémentation RNG basée sur SHA1, qui n'est pas aussi puissante que les algorithmes utilisés par les mécanismes DRBG approuvés.
Pendant ce temps, le Guide du développeur de sécurité Java 13 continue de lire
Sous Linux et macOS, si le périphérique de collecte d'entropie dans java.security est défini sur file:/dev/urandom
ou file:/dev/random
, NativePRNG est préféré à SHA1PRNG. Sinon, SHA1PRNG est préféré.
Pour clarifier la façon dont les nouveaux mécanismes DRBG jouent avec les PRNG précédents, j'exécute quelques tests sur macOS (Darwin) avec AdoptOpenJDK (build 13.0.2 + 8). Voici les résultats:
fichier: / dev / random
Ordre de préférence pour les fournisseurs:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
fichier: / dev / urandom
Ordre de préférence pour les fournisseurs:
SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG
fichier: / dev /./ urandom
Ordre de préférence pour les fournisseurs:
SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG
Conclusion:
Je recommande d'utiliser -Djava.security.egd=file:/dev/./urandom
pour vous assurer de tirer parti de l' implémentation SecureRandom la plus puissante disponible, quelle que soit la plateforme utilisée, tout en évitant de bloquer le code de manière inattendue.
/dev/urandom
sélectionne NativePRNG alimenté par/dev/urandom
tout/dev/./urandom
choix SHA1PRNG vers le haut (également alimentés par/dev/urandom
) lors de l' utilisation de Java 8. De Java 9 en avant, DRBG a priorité lorsque la/dev/./urandom
source est spécifiée.Ce n'est plus nécessaire si vous utilisez JDK 8 ou supérieur
Le problème a été corrigé par Java et voici quelques liens
Contour
Pour plus d'informations (recherchez aléatoire dans la page):
https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html
https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
la source
Ceci est lié à la différence entre Linux
/dev/random
et le/dev/urandom
générateur de nombres aléatoires.Tiré de ce lien
Pour répondre à ta question
Sur la base du lien ci-dessus, c'est quelque chose d'unique aux versions Java 5 et suivantes qui résulte de problèmes avec / dev / urandom sur les systèmes Linux en 2004.
la source