4

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

这是我所知道/看到的: - 重新启动乘客似乎暂时解决了问题 - 从控制台运行相同的代码按预期工作 - /dev/urandom 存在,因此它应该能够使用它来播种 - 这发生在 ubuntu 10.04 ,openssl 0.9.8k,ree 1.8.7 p253,passenger 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'

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

4

2 回答 2

0

假设/dev/random/dev/urandom都是可读/写的,并且您仍然收到此错误,也许您需要运行/安装熵生成器,例如prngd

尝试:

 $ sudo /etc/init.d/prngd start

如果失败,请先安装prngd

 $ sudo apt-get install prngd
于 2012-07-12T08:00:54.323 回答
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 是什么。

于 2012-07-18T23:12:43.013 回答