Ruby的OpenSSL :: Random的种子是否足够?

前端之家收集整理的这篇文章主要介绍了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

当然,Ruby还没有复活一个18岁的小虫.我在这里想念的是什么?

编辑:这是random_bytes的来源.请注意第一次检查是否使用OpenSSL编译ruby,在这种情况下,它会使用pid和当前时间对其进行种子处理.

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,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的配置:

Secure random number generator interface.

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

  • /dev/urandom

  • Win32

上述所有三个通常被认为是安全的.但是,如果它实际上是安全的,它取决于SecureRandom类的实现.了解这一点的唯一方法是对实施进行广泛的研究.

看看问题中的代码,很明显Ruby在additionally播种PID之后直接使用OpenSSL生成的字节:

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

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相关文章