Node.js 随机字节与伪随机字节

Node.js 随机字节与伪随机字节,node.js,security,Node.js,Security,在什么情况下(从安全的角度)可以接受使用节点的而不是加密强大的 我假设,pseudoRandomBytes性能更好,但代价是更可预测(),但文档并没有说它的强度有多低 具体地说,我想知道我是否可以使用伪随机字节来生成CSRF令牌。如果它与其他语言中的标准PRNG实现类似,那么它可能在默认情况下不是种子,或者是由一个简单的值(如时间戳)来种子。无论如何,种子可能很容易猜测。只是澄清一下,两者的性能相同: var crypto = require ("crypto") var speedy = re

在什么情况下(从安全的角度)可以接受使用节点的而不是加密强大的

我假设,
pseudoRandomBytes
性能更好,但代价是更可预测(),但文档并没有说它的强度有多低


具体地说,我想知道我是否可以使用
伪随机字节
来生成CSRF令牌。

如果它与其他语言中的标准PRNG实现类似,那么它可能在默认情况下不是种子,或者是由一个简单的值(如时间戳)来种子。无论如何,种子可能很容易猜测。

只是澄清一下,两者的性能相同:

var crypto = require ("crypto")
var speedy = require ("speedy");

speedy.run ({
    randomBytes: function (cb){
        crypto.randomBytes (256, cb);
    },
    pseudoRandomBytes: function (cb){
        crypto.pseudoRandomBytes (256, cb);
    }
});

/*
File: t.js

Node v0.10.25
V8 v3.14.5.9
Speedy v0.1.1

Tests: 2
Timeout: 1000ms (1s 0ms)
Samples: 3
Total time per test: ~3000ms (3s 0ms)
Total time: ~6000ms (6s 0ms)

Higher is better (ops/sec)

randomBytes
  58,836 ± 0.4%
pseudoRandomBytes
  58,533 ± 0.8%

Elapsed time: 6318ms (6s 318ms)
*/

事实证明,使用默认的OpenSSL(它与节点捆绑在一起,但如果您已经构建了自己的,则可以),对于
randomBytes
RAND\u bytes
)和
pseudoRandomBytes
RAND\u pseudo\u bytes
)两者都是完全相同的

两个调用之间唯一的区别取决于您使用的节点版本:

  • 在节点v0.12和更早版本中,
    randomBytes
    如果熵池尚未使用足够的数据进行播种,则返回错误
    pseudoRandomBytes
    将始终返回字节,即使熵池未正确播种
  • 在节点v4和更高版本中,
    randomBytes
    在熵池具有足够的数据之前不会返回。这应该只需要几毫秒(除非系统刚刚启动)
一旦为熵池添加了足够的数据,它将永远不会“用完”,因此,一旦熵池满了,
randomBytes
pseudoRandomBytes
之间绝对没有有效的区别


由于使用完全相同的算法生成randrom数据,因此两个调用之间的性能没有差异(尽管是一次性熵池播种).

我不知道它到底有多随机,但是
crypto.randomBytes
的性能一开始就是个问题吗?如果你需要一批CSRF令牌并且
crypto.randomBytes
太贵,你可以做一个
crypto.randomBytes
操作和n
crypto.pseudombytes
操作。然后将后者与前者进行异或运算,并使用它们。我不是密码专家,我不能保证这种方法的安全性。它可能比使用all
伪随机
要好,但比使用all
crypto.random
更糟糕。我们都知道数据库几乎总是一个瓶颈。假设
pseudoRandomBytes
是安全的,我怀疑您甚至不会看到性能上的差异。这不是优化的正确方向。浪费时间。只需使用
randomBytes
。我曾经遇到过crypto.randomBytes的问题。在没有太多可用熵的VM环境中,它的挂起时间可能比db@Plato好吧,这个问题在它存在之前是不存在的(而且不太可能发生)。此外,购买硬件随机数发生器(例如常春藤桥CPU)更容易、更快。毕竟我们生活在二十一世纪。我问的方法是如何使用的,所以我相当肯定它们是安全的。我说的是最初的种子。OpenSSL的PRNG使用的是
/dev/uradom
。它的内部RNG引擎会,是的,但这总是真的吗<代码>随机字节将是安全的,但是是什么使得随机伪字节可能不安全呢?由于它们应该调用相同的字节生成器,我认为种子的质量可能会更差。它们使用相同的种子,但是如果熵池没有足够的数据,
RAND\u bytes
将返回错误(而
RAND\u pseudo\u bytes
返回基于低熵种子的字节)。这并不是说种子很弱(只是一个时间戳),而是它不够大,不能保证安全;他们只是说“
randomBytes
将阻塞,直到有足够的熵。这通常不会超过几毫秒。”@bfred.it:这在v4中发生了变化。节点的旧版本。(“如果没有足够的累积熵来生成加密强数据,节点将抛出错误或调用带有错误的回调。换句话说,
crypto.randomBytes
没有回调,即使所有熵源都耗尽,也不会阻塞。”答案已更新。