在什么情况下(从安全角度来看)使用 node'scrypto.pseudoRandomBytes
而不是 cryptographically-strong是可以接受的crypto.randomBytes
?
我假设以更可预测(不正确)pseudoRandomBytes
为代价表现更好,但文档并没有太多关于它有多弱的说法。
具体来说,我想知道我是否可以pseudoRandomBytes
用来生成 CSRF 令牌。
在什么情况下(从安全角度来看)使用 node'scrypto.pseudoRandomBytes
而不是 cryptographically-strong是可以接受的crypto.randomBytes
?
我假设以更可预测(不正确)pseudoRandomBytes
为代价表现更好,但文档并没有太多关于它有多弱的说法。
具体来说,我想知道我是否可以pseudoRandomBytes
用来生成 CSRF 令牌。
事实证明,使用默认的 OpenSSL(与 node 捆绑在一起,但如果您已经构建了自己的引擎,则可以配置不同的引擎),生成随机数据的算法对于randomBytes
( RAND_bytes
) 和pseudoRandomBytes
( RAND_pseudo_bytes
)。
这两个调用之间的唯一区别取决于您使用的节点版本:
randomBytes
如果熵池尚未播种足够的数据,则返回错误。 pseudoRandomBytes
即使熵池没有正确播种,也将始终返回字节。randomBytes
直到熵池有足够的数据才返回。这应该只需要几毫秒(除非系统刚刚启动)。一旦熵池中播种了足够的数据,它就永远不会“用完”,因此randomBytes
,pseudoRandomBytes
一旦熵池已满,之间绝对没有有效的区别。
因为使用完全相同的算法来生成随机数据,所以两次调用之间的性能没有差异(尽管有一次性熵池播种)。
只是澄清一下,两者都具有相同的性能:
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)
*/
如果它与其他语言中的标准 PRNG 实现类似,那么它可能不是默认播种的,或者是由一个简单的值播种的,例如时间戳。无论如何,种子可能很容易猜到。