Ruby的种子为OpenSSL :: Random足够吗? [英] Is Ruby's seed for OpenSSL::Random sufficient?

查看:226
本文介绍了Ruby的种子为OpenSSL :: Random足够吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Ruby很少知道,所以如果这个答案很明显,请原谅我。我在 http://www.ruby-doc.org/stdlib上注意到了-1.9.3 / libdoc / securerandom / rdoc / SecureRandom.html ,当调用random_bytes时,Ruby使用pid和当前时间种子OpenSSL :: Random。除非在封底下发生其他事情,这不是Netscape在90年代中期在其初始SSL实现中使用的种子吗?
http://en.wikipedia.org/wiki/Random_number_generator_attack#Prominent_examples_of_random_number_generator_security_issues

I know very little about Ruby, so please forgive me if the answer to this is obvious. I noticed at http://www.ruby-doc.org/stdlib-1.9.3/libdoc/securerandom/rdoc/SecureRandom.html that Ruby uses the pid and the current time to seed OpenSSL::Random when a call to random_bytes is made. Unless something else happens under the covers, isn't this pretty much the seed that Netscape used in their initial SSL implementation in the mid 90s? http://en.wikipedia.org/wiki/Random_number_generator_attack#Prominent_examples_of_random_number_generator_security_issues

当然Ruby没有恢复一个18岁的bug。我在这里缺少什么?

Surely Ruby hasn't revived an 18 year old bug. What am I missing here?

编辑:这里是random_bytes的来源。请注意,首先检查ruby是否使用OpenSSL编译,在这种情况下,它将使用pid和当前时间进行种子。

Here's the source for random_bytes. Notice the first check to see if ruby was compiled with OpenSSL, in which case it seeds it with the pid and current time.

def self.random_bytes(n=nil)
  n = n ? n.to_int : 16

  if defined? OpenSSL::Random
    @pid = 0 if !defined?(@pid)
    pid = $$
    if @pid != pid
      now = Time.now
      ary = [now.to_i, now.nsec, @pid, pid]
      OpenSSL::Random.seed(ary.to_s)
      @pid = pid
    end
    return OpenSSL::Random.random_bytes(n)
  end

  if !defined?(@has_urandom) || @has_urandom
    flags = File::RDONLY
    flags |= File::NONBLOCK if defined? File::NONBLOCK
    flags |= File::NOCTTY if defined? File::NOCTTY
    begin
      File.open("/dev/urandom", flags) {|f|
        unless f.stat.chardev?
          raise Errno::ENOENT
        end
        @has_urandom = true
        ret = f.readpartial(n)
        if ret.length != n
          raise NotImplementedError, "Unexpected partial read from random device: only #{ret.length} for #{n} bytes"
        end
        return ret
      }
    rescue Errno::ENOENT
      @has_urandom = false
    end
  end

  if !defined?(@has_win32)
    begin
      require 'Win32API'

      crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext", 'PPPII', 'L')
      @crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom", 'LIP', 'L')

      hProvStr = " " * 4
      prov_rsa_full = 1
      crypt_verifycontext = 0xF0000000

      if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full, crypt_verifycontext) == 0
        raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}"
      end
      @hProv, = hProvStr.unpack('L')

      @has_win32 = true
    rescue LoadError
      @has_win32 = false
    end
  end
  if @has_win32
    bytes = " ".force_encoding("ASCII-8BIT") * n
    if @crypt_gen_random.call(@hProv, bytes.size, bytes) == 0
      raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}"
    end
    return bytes
  end

  raise NotImplementedError, "No random device"
end


推荐答案

这取决于使用RNG的Ruby配置:

It depends on the configuration of Ruby which RNG is used:


安全随机数生成器接口

此库是安全随机数生成器的接口,
适用于在HTTP cookie等中生成会话密钥。

This library is an interface for secure random number generator which is suitable for generating session key in HTTP cookies, etc.

它支持以下安全随机数生成器。

It supports following secure random number generators.


  • openssl

  • openssl

/ dev / urandom

Win32

以上一般被认为是安全的。但是,它取决于 SecureRandom 类的实现,如果它实际上是安全的。知道这一点的唯一方法是对实现的广泛研究。

All three of the above are generally considered secure. However, it depends on the implementation of the SecureRandom class if it actually is secure. The only way of knowing this is an extensive research into the implementations.

查看问题中的代码,很明显,Ruby直接使用OpenSSL生成的字节, a href =http://www.openssl.org/docs/crypto/rand.html#INTERNALS =nofollow> 另外 播种PID:

Looking at the code in the question it is clear that Ruby directly uses bytes generated by OpenSSL, after additionally seeding the PID:


每当添加种子数据时,都会将其插入到'state'中,如下所示。

Whenever seed data is added, it is inserted into the 'state' as follows.

输入被斩波为20字节的单位(或最后的
块的更小)。这些块中的每一个都通过散列函数运行,因为
如下:传递给散列函数的数据是当前的md,
与状态相同的字节数(由在
递增循环索引)作为当前'块',新的关键数据
'block'和'count'(其在每次使用之后递增)。其结果
保存在'md'中,并且在用作哈希函数的输入的相同
位置处被放入'状态'。我相信
这个系统将点1(散列函数;当前为SHA-1),3
('状态'),4(通过'md'),5函数和
xor)。

The input is chopped up into units of 20 bytes (or less for the last block). Each of these blocks is run through the hash function as follows: The data passed to the hash function is the current 'md', the same number of bytes from the 'state' (the location determined by in incremented looping index) as the current 'block', the new key data 'block', and 'count' (which is incremented after each use). The result of this is kept in 'md' and also xored into the 'state' at the same locations that were used as input into the hash function. I believe this system addresses points 1 (hash function; currently SHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash function and xor).

这篇关于Ruby的种子为OpenSSL :: Random足够吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆