2009-09-22 6 views
82

Est-ce que SecureRandom est sûr pour les threads? C'est-à-dire, après l'avoir initialisé, est-ce que l'accès au prochain nombre aléatoire peut être utilisé comme thread sécurisé? L'examen du code source semble montrer qu'il l'est, et this bug report semble indiquer que son manque de documentation en tant que thread sûr est un problème de javadoc. Est-ce que quelqu'un a confirmé qu'il est en fait thread sécurisé?Le thread SecureRandom est-il sécurisé?

Répondre

83

Oui, c'est le cas. Il étend Random, qui a toujours eu une de facto la mise en œuvre de threadsafe et, de Java 7, explicitly guarantees threadsafety.

Si plusieurs threads utilisent un seul SecureRandom, il pourrait y avoir affirmation que mal la performance. D'un autre côté, l'initialisation d'une instance SecureRandom peut être relativement lente. La meilleure façon de partager un RNG global ou d'en créer un nouveau pour chaque thread dépend de votre application. La classe ThreadLocalRandom peut être utilisée comme modèle pour fournir une solution prenant en charge SecureRandom.

+3

Merci pour la mise à jour. Bizarrement, le bug est marqué comme "ne corrigera pas". Mais ils l'ont réparé quand même. Eh bien, je ne les envie pas de la taille de leur base de données de bogues. – Yishai

+2

Initialiser un 'SecureRandom' peut non seulement être lent, mais peut potentiellement se bloquer en raison d'une entropie manquante –

+1

@WalterTross Hang? J'ai vu des systèmes prendre 10 ou 15 minutes, mais je n'en ai jamais vu. Une implémentation qui n'est pas garantie pour continuer à alimenter son pool d'entropie, bien que lentement, semble être un bogue dans le système d'exploitation. – erickson

1

Oui. C'est totalement sans danger pour les threads. En fait, je me plaindrais que la serrure soit trop agressive. L'ensemble engineNextBytes() est synchronisé. Pour être franc avec vous, je ne saurais pas si ce n'est pas sécuritaire. La question de threading introduit probablement plus de hasard :)

+9

C'est * Sécurisé * Au hasard, il est très important de l'utiliser avec précision. Je ne pense pas que cela introduit plus de hasard. Par exemple. Un thread non aléatoire peut produire le même nombre aléatoire dans plusieurs threads - cela pourrait signifier qu'un thread pourrait voler un nombre généré pour un autre thread, il pourrait être exploité par un hacker. – kan

8

L'implémentation actuelle de SecureRandom est thread-safe, spécifiquement les deux méthodes de mutations nextBytes(bytes[]) et setSeed(byte[]) sont synchronisées. Bien, autant que j'ai pu le dire, toutes les méthodes de mutation sont finalement routées par ces deux méthodes, et SecureRandom remplace quelques méthodes dans Random pour s'assurer que. Ce qui fonctionne mais pourrait être fragile si la mise en œuvre est modifiée à l'avenir.

La meilleure solution consiste à synchroniser manuellement sur l'instance SecureRandom en premier. Cela signifie que chaque pile d'appels va acquérir deux verrous sur le même objet, mais cela est généralement très bon marché sur les JVM modernes. Autrement dit, il n'y a pas grand mal à vous synchroniser explicitement. Par exemple:

SecureRandom rnd = ...; 

    byte[] b = new byte[NRANDOM_BYTES]; 
    synchronized (rnd) { 
     rnd.nextBytes(b); 
    } 
Questions connexes