RandomBytes vs pseudoRandomBytes
В каких ситуациях приемлемо (с точки зрения безопасности) использовать node crypto.pseudoRandomBytes
вместо криптографически сильного crypto.randomBytes
?
Я предполагаю, что pseudoRandomBytes
работает лучше за счет более предсказуемого (неверно), но документы действительно не имеют многое сказать о том, насколько он менее силен.
В частности, мне интересно, могу ли я использовать pseudoRandomBytes
для создания токена CSRF.
Ответы
Ответ 1
Как оказалось, с OpenSSL по умолчанию (который связан с node, но если вы создали свой собственный, можно настроить разные механизмы), алгоритм генерации случайных данных точно такой же как для randomBytes
(RAND_bytes
), и pseudoRandomBytes
(RAND_pseudo_bytes
).
Единственная разница между двумя вызовами зависит от версии node, которую вы используете:
- В node v0.12 и ранее
randomBytes
возвращает ошибку, если пул энтропии еще не был засеян достаточным количеством данных. pseudoRandomBytes
всегда будет возвращать байты, даже если пул энтропии не был правильно засеян.
- В node v4 и более поздних версиях
randomBytes
не возвращается, пока в пуле энтропии не будет достаточно данных. Это займет всего несколько миллисекунд (если только система не загрузилась).
После того, как пул энтропии будет заселен достаточным количеством данных, он никогда не "исчерпает", поэтому нет полной разницы между randomBytes
и pseudoRandomBytes
после заполнения энтропийного пула.
Поскольку тот же самый алгоритм используется для генерации данных randrom, нет никакой разницы в производительности между двумя вызовами (несмотря на одноразовый посев энтропийного пула).
Ответ 2
Просто уточнение, оба имеют одинаковую производительность:
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)
*/
Ответ 3
Если это что-то похожее на стандартные реализации PRNG на других языках, возможно, либо не высевается по умолчанию, либо поселяется простым значением, например меткой времени. Несмотря на это, семя, возможно, очень легко угадывается.