与其他方法相比,红宝石兰特的安全性

Dor*_*ian 2 ruby security random

以下是什么之间的安全区别:

rand(10**100).to_s(16)
# => "a8ef61cbac3b770580cdebb55c1d2cf65cf32b5df57ef44a3bea4658ff66ac37f93b540bfb4c2ddc33e"
Run Code Online (Sandbox Code Playgroud)

和RandomSecure以及所有其他人?是rand(...).to_s(...)足够安全?

Sch*_*ern 5

问题永远不是"这是安全吗?" 问题是"这对我正在做的事情是否足够安全?" 我不知道你在做什么.

OpenSSL :: Random是加密安全的,但是使用它会有点痛苦.这很好,因为你不应该尝试编写自己的加密代码!使用图书馆.

我可以说既不是加密安全的PRNG Random也不Kernel#rand是加密安全的PRNG.SecureRandom可能是,并且"可能是安全的"并不会削减它.但是,它们非常好.比起C标准库附带的大多数rand函数要好得多.

长话短说,安全性与链条中最薄弱的环节一样好.如果您不太了解安全问题的使用方式,那么Ruby PRNG将不会成为最薄弱的环节.你是.没有冒犯意味着,但安全漏洞往往是程序员错误而不是弱算法.


来自随机文档 ......

PRNG目前作为修改后的Mersenne Twister实施,期限为2**19937-1.

Mersenne Twister是一个坚实的PRNG,被许多,许多语言和图书馆使用.它比大多数系统PRNG更好,更好.

但是,MT 不具有加密安全性!如果您观察到大约1000个随机数,则可以预测输出.它可以更安全,但没有迹象表明Ruby已经做到了.

但是Randomrand...... 更好

[Random#rand]提供了Kernel#rand的基本功能以及更好的浮点值处理.这些都是Random :: DEFAULT,Ruby系统PRNG的接口.

:: new将创建一个新的PRNG,其状态独立于Random :: DEFAULT,允许具有不同种子值或序列位置的多个生成器同时存在.可以对随机对象进行编组,从而允许保存和恢复序列.

prng = Random.new; puts prng.randputs rand因为每个单独的实例Random将使用不同的种子(因此使用不同的伪随机模式),而每次调用rand都使用相同的种子.

如果您的代码rand用于生成随机数,则攻击者可以假设任何随机数使用相同的种子和相同的序列.然后他们可以更快地收集观察结果来猜测种子.

如果您的代码的每个部分都使用自己的代码Random.new,那么攻击者现在必须确定哪个随机数与哪个种子相关.这使得构建一系列随机数变得更加困难,并且使攻击者可以使用更少的数字.


你的随机数生成器只有它的种子一样好.随机和内核#rand都使用...

如果省略number,则使用操作系统提供的熵源(如果可用)(Unix系统上的/ dev/urandom或Windows上的RSA加密提供程序)为发生器播种,然后将时间与进程ID相结合,和序号.

/dev/urandom 这些天很不错,我不了解Windows,但最终取决于操作系统及其版本.


那么SecureRandom呢?

该库是用于保护随机数生成器的接口,适用于在HTTP cookie等中生成会话密钥.

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

OpenSSL的

的/ dev/urandom的

Win32的

这并没有告诉我们多少.窥视实现,它只是OpenSSL :: Random的种子生成器.

               # File securerandom.rb, line 51
def self.gen_random(n)
  @pid = 0 unless defined?(@pid)
  pid = $$
  unless @pid == pid
    now = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond)
    OpenSSL::Random.random_add([now, @pid, pid].join(""), 0.0)
    seed = Random.raw_seed(16)
    if (seed)
      OpenSSL::Random.random_add(seed, 16)
    end
    @pid = pid
  end
  return OpenSSL::Random.random_bytes(n)
end
Run Code Online (Sandbox Code Playgroud)

它正在为OpenSSL::Random进程id,系统时钟以及来自Random.raw_seed(即/dev/urandom)的任何内容组成自己的种子.我真的不能说这是否具有加密安全性,也不能仅仅让它OpenSSL::Random.random_bytes选择自己的种子.

谈到加密,更多可以更少.

它有一些很好的方法来格式化随机字节.


如果您想要加密安全的PRNG,请使用OpenSSL :: Random.

require 'openssl'
rand = OpenSSL::Random.random_bytes
Run Code Online (Sandbox Code Playgroud)

这不会产生数字,它会产生一个字节流,这是你真正想要的密码学.如果这对您没有任何意义,请不要编写加密代码(但请查看它!).