我對Ruby知之甚少,所以請原諒我,如果這個答案很明顯。我注意到http://www.ruby-doc.org/stdlib-1.9.3/libdoc/securerandom/rdoc/SecureRandom.html Ruby在使用pid和當前時間調用random_bytes時播種OpenSSL :: Random。除非在封面下發生了其他事情,否則Netscape在90年代中期初始SSL實施中使用的種子是不是很多? http://en.wikipedia.org/wiki/Random_number_generator_attack#Prominent_examples_of_random_number_generator_security_issuesOpenSSL :: Random的Ruby種子是否足夠?
當然,Ruby還沒有恢復一個18歲的bug。我在這裏錯過了什麼?
編輯:這是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, 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
它沒有很好的記錄,是嗎?看看OpenSSL提供的值是什麼,可以更仔細地查看源代碼。它應該使用任何OS級別的隨機設施,比如'/ dev/urandom'或'/ dev/random',而不是像這樣的東西。 – tadman
注意到我發現了一些關於分叉如何導致漏洞的討論,這對於Ruby調用OpenSSL的方式來說並不是很好。 –
你能指出它在哪裏聲明Ruby使用pid和當前時間作爲(唯一)種子? –