À quoi sert l'option java.security.egd?

23

Dans un projet sur lequel je travaille, l'application est lancée à l'aide d'une commande similaire à celle-ci:

java -Djava.security.egd=file:/dev/urandom -jar app.jar

Je n'ai jamais vu l' java.security.egdoption auparavant. En cherchant un peu, il semble utilisé pour configurer la génération de nombres aléatoires dans une application Java.

Est ce juste? Quand est-il censé être appliqué?

davioooh
la source

Réponses:

30

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/randomun 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/urandomne 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/arandomqui 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/./urandomde l'invocation de ligne de commande utilisée pour démarrer le processus Java indique à la JVM d'utiliser à la /dev/urandomplace.

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/urandomest spécifié.

Enfin, il existe un mythe qui /dev/urandomest un générateur de nombres pseudo-aléatoires, un PRNG, alors qu'il /dev/randomest un "vrai" générateur de nombres aléatoires . Ce n'est tout simplement pas vrai, les deux /dev/randomet /dev/urandomsont 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/randomblocs, tandis /dev/urandomque 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}randomsur 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/urandomou 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/./urandompour 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.

dbaltor
la source
1
Depuis Java 8, la "solution de contournement obscure" de l'extrait ./ dans le nom de fichier n'est plus nécessaire, vous pouvez donc simplement utiliser "/ dev / urandom", voir: docs.oracle.com/javase/8/docs / technotes / guides / sécurité /…
Kamal
Merci d'avoir mis à jour la réponse (spécialement sur les changements dans Java 9 et 13). Si je comprends bien, à partir de Java 8, définir le "dispositif de collecte d'entropie" sur / dev / urandom ou /dev/./urandom devrait donner exactement les mêmes résultats, sinon le correctif n'aurait pas de sens. Du point de vue du système d'exploitation, ceux-ci pointent vers le même fichier identique, de sorte que cela ne devrait pas affecter Java (il l'a fait avant le correctif, mais c'était un bogue, pas une fonctionnalité prévue). Par conséquent, votre déclaration "L'extra /./ est nécessaire pour influencer la sélection PRNG." ne devrait plus être vrai, à partir de Java 8.
Kamal
Merci @Kamal pour vos commentaires. Ma phrase précédente "sélection PRNG" n'était pas assez claire. Je l'ai reformulé pour préciser que je parle de l'algorithme utilisé: NativePRNG ou SHA1PRNG. L'utilisation de /dev/urandomsélectionne NativePRNG alimenté par /dev/urandomtout /dev/./urandomchoix 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/./urandomsource est spécifiée.
dbaltor
1

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

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.)

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

Venu Madhav
la source
Je ne pense pas que ce soit correct. Pour l'arrière-plan: tersesystems.com/blog/2015/12/17/… Les correctifs de Java 8 indiquent uniquement qu'ils respectent désormais les propriétés de la source de départ SecureRandom dans le fichier java.security. Mais par défaut, il contient toujours: securerandom.source = file: / dev / random La "solution de contournement obscure" fait référence au supplément ./ dans le nom du fichier, également mentionné par la réponse acceptée (et la plus votée) ici.
Kamal
La «solution de contournement obscure» n'était requise que dans des circonstances spécifiques, voir: bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
Kamal
@Kamal Les liens que vous avez publiés se réfèrent à Java 6 et versions antérieures,
Venu Madhav
C'est exactement le point, il a été corrigé dans Java 8. Selon le rapport de bogue, la "solution de contournement obscure" (en ajoutant le ./ supplémentaire dans le nom du fichier) était requise après Java 1.4.2 et jusqu'à 6. Je suppose dans Java 7 également, sinon il ne serait pas mentionné comme étant corrigé dans Java 8. Cependant, la définition de / dev / urandom au lieu de / dev / random est toujours requise si vous souhaitez utiliser un périphérique non bloquant.
Kamal
0

Ceci est lié à la différence entre Linux /dev/randomet le /dev/urandomgénérateur de nombres aléatoires.

Tiré de ce lien

Le bogue Java 6202721 indique que java.security.SecureRandom utilise / dev / random plutôt que / dev / urandom même si / dev / urandom est spécifié car à l'époque (vers 2004) / dev / urandom ne fonctionnait pas correctement. Le bogue n'a jamais été inversé maintenant que / dev / urandom fonctionne assez bien. Par conséquent, vous devez le simuler en masquant le paramètre en utilisant /dev/./urandom pour forcer l'utilisation de SHA1PRNG plutôt que / dev / random.

Pour répondre à ta question

Quand est-il censé être appliqué?

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.

Ruelos Joel
la source
Il y a probablement une faute de frappe dans cet article, car le bogue Java 6202721 déclare en fait "C'est un problème si / dev / urandom a été choisi parce que / dev / random ne fonctionne pas correctement.". Par conséquent, votre conclusion "résultant de problèmes avec / dev / urandom" est incorrecte. Voir la réponse acceptée pour une explication sur le choix de / dev / urandom au lieu de la valeur par défaut (/ dev / random). C'est une bonne idée dans la plupart des cas.
Kamal