PRNG没有播种错误

时间:2012-07-08 11:01:13

标签: ruby-on-rails ruby openssl prng

我收到间歇性错误,说在尝试生成表单身份验证令牌时没有播种伪随机数生成器。我已经复制了下面堆栈跟踪的相关部分。

这是我所知道/看到的: - 重新启动乘客似乎暂时解决了这个问题 - 从控制台运行相同的代码按预期工作 - / dev / urandom存在,所以它应该能够使用它来播种 - 这发生在ubuntu 10.04上,openssl 0.9.8k,ree 1.8.7 p253,乘客3.0.3。 - 我已经读过关于独角兽的一个问题,听起来有点像重新启动工作人员但没有看到乘客所描述的那样。

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'

非常难过。任何帮助非常感谢。

2 个答案:

答案 0 :(得分:0)

假设/dev/random/dev/urandom都是可读/可写的并且您仍然收到此错误,那么您可能需要运行/安装prngd之类的熵生成器吗?

尝试:

 $ sudo /etc/init.d/prngd start

如果失败,请先安装prngd

 $ sudo apt-get install prngd

答案 1 :(得分:0)

一个牵强的假设。代码的相关位应该是(可能是不同版本):

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

我们知道,如果使用少于128位的熵,OpenSSL会报告您报告的错误。总共16个字节(或18..22,如果OpenSSL足够聪明,可以发现一串ASCII可打印字符并忽略高位)。

初始化OpenSSL的序列类似于,1342652367.A.0.B;可能有时候,pid足够小,微秒接近于零,结果熵低于临界阈值?

这应该很容易测试:替换

ary.join('.')

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

为了确保128位,可能是偶数256位的字符串长度具有合理的不可预测性。

更明确的检查是添加例外并打印出触发错误时ary是什么。