简体   繁体   English

PRNG没有播种错误

[英]PRNG not seeded error

i'm getting an intermittent error saying that the pseudo random number generator is not seeded when trying to generate the form auth token. 我收到一个间歇性错误,说在尝试生成表单身份验证令牌时没有播种伪随机数生成器。 i've copied the relevant part of the stack trace below. 我已经复制了下面的堆栈跟踪的相关部分。

here's what i know/see: - restarting passenger seems to temporarily fix the issue - running the same code from the console works as expected - /dev/urandom exists so it should be able to use that to seed - this is happening on ubuntu 10.04, with openssl 0.9.8k, ree 1.8.7 p253, and passenger 3.0.3. 这就是我知道/看到的: - 重启乘客似乎暂时解决了问题 - 从控制台运行相同的代码按预期工作 - / dev / urandom存在所以它应该能够使用它来播种 - 这发生在ubuntu 10.04上,openssl 0.9.8k,ree 1.8.7 p253,乘客3.0.3。 - i've read about an issue on unicorn that sounds sorta like it that happens when restarting workers but haven't seen anything like that described on passenger. - 我已经读过关于独角兽的一个问题,听起来有点像在重新启动工作人员时发生但却没有看到像乘客所描述的那样。

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'

pretty stumped. 很难过。 any help greatly appreciated. 任何帮助非常感谢。

Assuming both /dev/random and /dev/urandom are read/writeable and you are still getting this error, maybe you need to run/install an entropy generator like prngd ? 假设/dev/random/dev/urandom都是可读/可写的并且您仍然遇到此错误,那么您是否需要运行/安装像prngd这样的熵生成器?

Try: 尝试:

 $ sudo /etc/init.d/prngd start

And if that fails, install prngd first: 如果失败,请先安装prngd

 $ sudo apt-get install prngd

A farfetched hypothesis. 一个牵强的假设。 The relevant bit of code should be something like (possibly this is not the same 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

and we know that OpenSSL gives the error you reported if fed with less than 128 bits of entropy. 我们知道,如果使用少于128位的熵,OpenSSL会给出您报告的错误。 Which is 16 bytes in all (or 18..22, if OpenSSL is clever enough to spot a string of ASCII printable characters and ignore the high bit). 总共16个字节(或18..22,如果OpenSSL足够聪明,可以发现一串ASCII可打印字符并忽略高位)。

The sequence initializing OpenSSL is something like, 1342652367.A.0.B; 初始化OpenSSL的序列类似于,1342652367.A.0.B; could it be possible that, sometimes, pid is small enough, and microseconds is near enough to zero, that the resulting entropy falls below the critical threshold? 可能有时候,pid足够小,微秒接近于零,导致的熵低于临界阈值?

This should be quite easy to test: replace 这应该很容易测试:替换

ary.join('.')

with

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

in order to have a surely-128 bit, possibly-even-256 bit string length of reasonable unpredictability. 为了确保128位,可能是偶数256位的字符串长度具有合理的不可预测性。

A more definite check would be to add an exception and print out what ary was when the error was triggered. 更明确的检查是添加异常并打印出错误被触发时ary是什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM