26

在什么情况下(从安全角度来看)使用 node'scrypto.pseudoRandomBytes而不是 cryptographically-strong是可以接受的crypto.randomBytes

我假设pseudoRandomBytes以更可预测(不正确)为代价表现更好,但文档并没有太多关于它有多弱的说法。

具体来说,我想知道我是否可以pseudoRandomBytes用来生成 CSRF 令牌。

4

3 回答 3

44

事实证明,使用默认的 OpenSSL(与 node 捆绑在一起,但如果您已经构建了自己的引擎,则可以配置不同的引擎),生成随机数据的算法对于randomBytes( RAND_bytes) 和pseudoRandomBytes( RAND_pseudo_bytes)。

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

  • 在节点 v0.12 及之前的版本中,randomBytes如果熵池尚未播种足够的数据,则返回错误。 pseudoRandomBytes即使熵池没有正确播种,也将始终返回字节。
  • 在节点 v4 及更高版本中,randomBytes直到熵池有足够的数据才返回。这应该只需要几毫秒(除非系统刚刚启动)。

一旦熵池中播种了足够的数据,它就永远不会“用完”,因此randomBytespseudoRandomBytes 一旦熵池已满,之间绝对没有有效的区别。

因为使用完全相同的算法来生成随机数据,所以两次调用之间的性能没有差异(尽管有一次性熵池播种)。

于 2013-08-08T16:57:31.797 回答
17

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

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)
*/
于 2013-08-08T16:40:41.547 回答
0

如果它与其他语言中的标准 PRNG 实现类似,那么它可能不是默认播种的,或者是由一个简单的值播种的,例如时间戳。无论如何,种子可能容易猜到。

于 2013-08-08T15:43:59.587 回答