2012-07-08 2 views
3

Je reçois une erreur intermittente indiquant que le générateur de nombres pseudo-aléatoires n'est pas ensemencé lors de la tentative de génération du jeton d'authentification de formulaire. J'ai copié la partie pertinente de la trace de la pile ci-dessous.PRNG erreur non ensemencée

Voici ce que je sais/voir: - le redémarrage de passagers semble fixer temporairement la question - exécutant le même code de la console fonctionne comme prévu -/dev/urandom existe donc il devrait être en mesure d'utiliser pour les semences - cela se passe sur Ubuntu 10.04, avec openssl 0.9.8k, ree 1.8.7 p253, et passager 3.0.3. - J'ai lu sur un problème sur la licorne qui ressemble un peu à ce qui se passe lors du redémarrage des travailleurs, mais n'a rien vu de tel que décrit sur le passager.

SessionsController#new (ActionView::TemplateError) "PRNG not seeded" 
/usr/local/lib/ruby/1.8/securerandom.rb:53:in `random_bytes' 
/usr/local/lib/ruby/1.8/securerandom.rb:53:in `random_bytes' 
/usr/local/lib/ruby/1.8/securerandom.rb:105:in `base64' 
vendor/bundle/ruby/1.8/gems/actionpack-2.3.14/lib/action_controller/request_forgery_protection.rb:109:in `form_authenticity_token' 
(eval):2:in `send' 
(eval):2:in `form_authenticity_token' 

assez perplexe. toute aide grandement appréciée.

+0

Quel système d'exploitation? Serait-ce que 'SecureRandom' n'a pas assez d'entropie? – Linuxios

+0

Ressemble à Ubuntu 10.04. –

+0

quelles indications dois-je rechercher pour déterminer si elle n'a pas assez d'entropie? Je ne pensais pas que ce serait un problème puisque la version de openssh utilise/dev/urandom, mais je ne suis pas un expert en la matière. – hubert

Répondre

0

En supposant à la fois /dev/random et /dev/urandom sont en lecture/écriture et que vous obtenez toujours cette erreur, peut-être que vous devez exécuter/installer un générateur d'entropie comme prngd?

Essayez:

$ sudo /etc/init.d/prngd start 

Et si cela échoue, installez prngd premier:

$ sudo apt-get install prngd 
0

Une hypothèse farfelue. Le bit correspondant du code doit être quelque chose comme (peut-être ce n'est pas la même version):

def self.random_bytes(n=nil) 
    n ||= 16 
    if defined? OpenSSL::Random 
    @pid = 0 if !defined?(@pid) 
    pid = $$ 
    if @pid != pid 
     now = Time.now 
     ary = [now.to_i, now.usec, @pid, pid] 
     OpenSSL::Random.seed(ary.join('.')) 
     @pid = pid 
    end 
    return OpenSSL::Random.random_bytes(n) 
end 

et nous savons que OpenSSL donne l'erreur que vous avez signalé si nourris avec moins de 128 bits d'entropie. Ce qui est de 16 octets en tout (ou 18..22, si OpenSSL est assez intelligent pour repérer une chaîne de caractères ASCII imprimables et ignorer le bit haut).

La séquence initialisant OpenSSL est quelque chose comme, 1342652367.A.0.B; pourrait-il être possible que, parfois, pid est assez petit, et microsecondes est assez proche de zéro, que l'entropie qui en résulte tombe en dessous du seuil critique?

Cela devrait être assez facile à tester: remplacer

ary.join('.') 

avec

Digest::MD5.hexdigest(ary.join('.')) 

afin d'avoir une longueur sûrement-128 bits, chaîne de bits peut-même-256 d'imprévisibilité raisonnable. Une vérification plus précise serait d'ajouter une exception et d'imprimer ce qui était quand l'erreur a été déclenchée.

Questions connexes