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
解决方法
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).