gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 06:53:41 25 4
gpt4 key购买 nike

我对 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 的来源。请注意第一次检查 ruby​​ 是否使用 OpenSSL 编译,在这种情况下,它使用 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

最佳答案

SecureRandom 中使用的种子禁止在 PID 被回收时出现可预测的随机数。如果不修复 SecureRandom,OpenSSL 的随机数生成器将在具有相同 PID 的不同进程中生成完全相同的值。

#4579概述了这是如何发生的,corresponding entry在 OpenSSL 的邮件列表上或多或少地告诉我们,这必须在客户端代码中处理。这就是为什么在 Ruby 中选择这个种子来防止安全威胁的原因。如果不相信,请运行 script Eric Wong 附上了此修复之前的 Ruby 版本,以了解这到底是怎么回事。

添加到 owlstead 的解释中,此时为 OpenSSL 的 RNG 播种不会危及安全性,因为未初始化的随机生成器将始终首先调用 RAND_poll,这将收集足够的熵,而不管值之前是否已经存在是否播种/添加。

但是,由于 SecureRandom 中的种子值显然是可以预测的,因此我们不应假设它们会增加任何熵。 OpenSSL 的内部行为可能会在某个时候发生变化,如果认为已经播种的值包含足够的熵,它可能会跳过初始熵收集。

因此我打开了#6928 ,这将选择一种更具防御性的方法,假设添加到区分不同进程的熵池的值没有熵 - 这将迫使 OpenSSL 在所有情况下可靠地收集足够的熵。

总而言之,值(PID 和时间)的选择是明智的,它甚至增加了整体安全性(通过防止“回收 PID 攻击”)而不是降低它。

关于ruby - Ruby 的 OpenSSL::Random 种子是否足够?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12118406/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com